The goal of this discussion is to put together a guide for crafting error messages throughout vim; eventually the guide can be incorporated into the developer docs. You can add you comments and preferences. In addition, specific messages that aren't right, or should be improved, can be mentioned.
Here's someinitial comments copied from elsewhere. The initial focus is vim9class.
Change E46 to E1335 as appropriate for vim9class
E46: Cannot change read-only variable "value"
E1335: Member is not writable: value
Some things to consider
- Only vim9script, particularly classes, related.
- Use a different error code where appropriate, like use `E1335` instead `E46`.
- Spec change from `member` to `variable`; for a class `function` to `method`.
Should messages be changed from `member` to `variable`? Other nomenclature changes?
- Style issues, for example should class/method/variable names be quoted? Or `this one: item`
Compare `E1335` versus `E46` above.
I guess consistency was guaranteed by the style guide in Bram's head.
There is not much unfortunately. I would think it should go into https://github.com/vim/vim/blob/master/runtime/doc/develop.txt
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
In #13136 there's a suggested change to
E1335: Variable "value" in "class C" is not writable
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Very good discussion!
What in my opinion would be possible to do:
—
Reply to this email directly, view it on GitHub,.
You are receiving this because you are subscribed to this thread.![]()
It seems to me that the word "class" does not need to be enclosed in quotation marks. This is a generic name. Like a wolf, a cat, a ship, but the name of the class itself needs to be enclosed in quotation marks. This is the unique name of this particular class.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
It seems to me that the word "class" does not need to be enclosed in quotation marks
I wondered about that myself. I guess the fact that class A appears explicitly in the text swayed me. I think you're right.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
But all this will require a fairly large amount of work, including changing the documentation. And, perhaps, it will affect compatibility with previous versions of the program and third-party plug-ins.
The more perspectives the better, but I suspect compatibility with previous releases (does that mean vim9.0 or last week) is a requirement. @chrisbra ?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Here's some specific vim9 related message issues
Maybe biggest issue is to get messages in sync with spec. member versus variable. Here's one example where member is used. There are many
Note member versus variable; variable versus method
EXTERN char e_static_member_not_supported_in_interface[]
INIT(= N_("E1378: Static member not supported in an interface"));
EXTERN char e_private_variable_not_supported_in_interface[]
INIT(= N_("E1379: Private variable not supported in an interface"));
EXTERN char e_private_method_not_supported_in_interface[]
INIT(= N_("E1380: Private method not supported in an interface"));
Are both these needed
EXTERN char e_using_null_object[]
INIT(= N_("E1360: Using a null object"));
EXTERN char e_cannot_use_non_null_object[]
INIT(= N_("E1362: Cannot use a non-null object"));
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
In this message, it doesn't include the class
e_cannot_access_private_member_str
Here's one place it's used, private message doesn't use class, the other does.
char *msg = (m->ocm_access == VIM_ACCESS_PRIVATE)
? e_cannot_access_private_member_str
: e_member_is_not_writable_str;
semsg(_(msg), m->ocm_name, cl->class_name);
return FALSE;
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
From my opinion, I would suggest not to change existing error codes (the messages could be changed, but please be careful with this, as this will require a huge amount of work for all translators) and this will also require changes in documentation and cause backwards incompatibilities (if we change say E19 to E1019 or similar that will make it hard to help people with older Vim releases) Except for the new Vim9 class features, for which I am fine with changing those however if this is not too much amount of work.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Grouping would have been nice, but that ship has sailed for current messages. There are a lot of materials that reference these messages (Q&A on Vi and Vim StackExchange, for example) that would be invalidated by changing error codes.
Perhaps future codes can and should be grouped?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
From my opinion, I would suggest not to change existing error codes (the messages could be changed, but please be careful with this, as this will require a huge amount of work for all translators)
I have some experience with this and was forced to 'learn' half a dozen new languages prior to the Vim9 release. If there are extensive changes then the onus should probably be on the project to provide updates for the translators to approve.
Like most global runtime maintenance issues this can be a little like herding cats.
Perhaps more significantly, error codes are essentially pseudo-exception types. See :help :catch
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
We should come up with the guidelines for new error messages. We can update the recently added error
messages for Vim9 class support. We should not change the older error messages (as this will have
a big impact on translations and other docs as described above).
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@errael , @yegappan
If it is still decided to use variable vs member and function vs method, then, as it seems to me, it should look like this:
EXTERN char e_variable_is_not_writable_str[]
INIT(= N_("E1335: Variable \"%s\" in class \"%s\" is not writable"));
otherwise, it turns out a complete discrepancy
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
The PR's #13136.
And for class, it's method instead of function.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
For reference, the following is a list of new error messages introduced after the Vim 9.0 release:
E418: I'm a teapot
E503: Coffee is currently not available
E614: Class required
E616: Object required for argument %d
E693: List or Class required for argument %d
E706: Argument of %s must be a List, String or Dictionary
E1291: Invalid argument: %ld
E1292: Command-line window is already open
E1293: Cannot use a negative id after adding a textprop with text
E1294: Can only use text_align when column is zero
E1295: Cannot specify both 'type' and 'types'
E1296: Can only use left padding when column is zero
E1297: Non-NULL Dictionary required for argument %d
E1298: Non-NULL List required for argument %d
E1299: Window unexpectedly closed while searching for tags
E1300: Cannot use a partial with dictionary for :defer
E1301: String, Number, List or Blob required for argument %d
E1302: Script variable was deleted
E1303: Custom list completion function does not return a List but a %s
E1304: Cannot use type with this variable: %s
E1305: Cannot use \"length\", \"end_col\" and \"end_lnum\" with \"text\"
E1306: Loop nesting too deep
E1307: Argument %d: Trying to modify a const %s
E1308: Cannot resize a window in another tab page
E1309: Cannot change mappings while listing
E1310: Cannot change menus while listing
E1311: Cannot change user commands while listing
E1312: Not allowed to change the window layout in this autocmd
E1313: Not allowed to add or remove entries (%s)
E1314: Class name must start with an uppercase letter: %s
E1315: White space required after name: %s
E1316: Class can only be defined in Vim9 script
E1317: Invalid object member declaration: %s
E1318: Not a valid command in a class: %s
E1319: Using a class as a Number
E1320: Using an object as a Number
E1321: Using a class as a Float
E1322: Using an object as a Float
E1323: Using a class as a String
E1324: Using an object as a String
E1325: Method not found on class \"%s\": %s
E1326: Member not found on object \"%s\": %s
E1327: Object required, found %s
E1328: Constructor default value must be v:none: %s
E1330: Invalid type for object member: %s
E1331: Public must be followed by \"this\" or \"static\"
E1332: Public member name cannot start with underscore: %s
E1333: Cannot access private member: %s
E1335: Member is not writable: %s
E1336: Internal error: shortmess too long
E1337: Class member \"%s\" not found in class \"%s\"
E1339: Cannot add a textprop with text after using a textprop with a negative id
E1340: Argument already declared in the class: %s
E1341: Variable already declared in the class: %s
E1342: Interface can only be defined in Vim9 script
E1343: Interface name must start with an uppercase letter: %s
E1344: Cannot initialize a member in an interface
E1345: Not a valid command in an interface: %s
E1346: Interface name not found: %s
E1347: Not a valid interface: %s
E1348: Member \"%s\" of interface \"%s\" is not implemented
E1349: Method \"%s\" of interface \"%s\" is not implemented
E1350: Duplicate \"implements\"
E1351: Duplicate interface after \"implements\": %s
E1352: Duplicate \"extends\"
E1353: Class name not found: %s
E1354: Cannot extend %s
E1355: Duplicate function: %s
E1356: \"super\" must be followed by a dot
E1357: Using \"super\" not in a class function
E1358: Using \"super\" not in a child class
E1359: Cannot define a \"new\" function in an abstract class
E1360: Using a null object
E1361: Cannot use color \"none\", did you mean \"NONE\"?
E1362: Cannot use a non-null object
E1363: Incomplete type
E1364: Warning: Pointer block corrupted
E1365: Cannot use a return type with the \"new\" function
E1366: Cannot access private method: %s
E1367: Access level of member \"%s\" of interface \"%s\" is different
E1368: Static cannot be followed by \"this\" in a member name
E1369: Duplicate member: %s
E1370: Cannot define a \"new\" function as static
E1371: Abstract must be followed by \"def\" or \"static\"
E1372: Abstract method \"%s\" cannot be defined in a concrete class
E1373: Abstract method \"%s\" is not implemented
E1374: Class member \"%s\" accessible only inside class \"%s\"
E1375: Class member \"%s\" accessible only using class \"%s\"
E1376: Object member \"%s\" accessible only using class \"%s\" object
E1377: Access level of method \"%s\" is different in class \"%s\"
E1378: Static member not supported in an interface
E1379: Private variable not supported in an interface
E1380: Private method not supported in an interface
E1381: Interface cannot use \"implements\"
E1382: Member \"%s\": type mismatch, expected %s but got %s
E1383: Method \"%s\": type mismatch, expected %s but got %s
E1400: Cannot mix positional and non-positional arguments: %s
E1401: format argument %d unused in $-style format: %s
E1402: Positional argument %d used as field width reused as different type: %s/%s
E1403: Positional argument %d out of bounds: %s
E1404: Positional argument %d type used inconsistently: %s/%s
E1405: Invalid format specifier: %s
E1408: Internal error: ap_types or ap_types[idx] is NULL: %d: %s
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Maybe new printf messages could start at E1600 to leave room for vim9script additions/extensions.
Is a couple hundred OK?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Examples with questions for consideration.
(I didn't look at code so just guessing what's what)
(Changed E1335 to current value)
E1325: Method not found on class \"%s\": %s
Method \"%s\" not found in class \"%s\"
E1326: Member not found on object \"%s\": %s
Variable \"%s\" not found in class \"%s\"
E1333: Cannot access private member: %s
Cannot access private variable \"%s\" in class \"%s\"
E1335: Variable \"%s\" in class \"%s\" is not writable
E1337: Class member \"%s\" not found in class \"%s\"
Class variable \"%s\" not found in class \"%s\"
For E1325 and E1326 could use the word object
E1325: Object method ... and E1326: Object variable ...
Maybe the rule could be, for example compare E1326 and E1337
object, then leave that word out.class include that word.Or could just leave out class/object and use the same message for both
Variable \"%s\" not found in class \"%s\"
For the purpose of reporting the problem, "Cannot access private", "not writable",
"not found", does it matter if it's object/class? In some cases?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
For something like
Cannot access private variable \"%s\" in class \"%s\"
should the class be the one that's being referenced, or the super class where it's defined?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@errael
I probably didn't say it very accurately.
It meant the name in the definition of the array.
EXTERN char e_variable_is_not_writable_str[]
EXTERN char e_member_is_not_writable_str[]
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Didn't notice that, my focus is currently user visible. That difference in the code doesn't bother me that much, and I'm not sure how/if it's best handled. If member needs to be changed everywhere in the code (and other similar changes), you can get into diff hell. The vim developer understands member/variable. Given the huge number of error messages in vim, I'm not sure names can be chosen such that it won't be required to consult errors.h.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
If member needs to be changed everywhere in the code (and other similar changes), you can get into diff hell
Yes, having a quick run through vim9compile.c, I agree with you. But if there's anywhere to start changing variable instead of member, it's at least with the definitions of arrays containing error messages, it seems to me.
The vim developer understands member/variable.
Although, on the other hand, as I recall, it was always said that Vim is an editor for programmers. And if a Vim developer understands the member/variable distinction, why wouldn't a script developer, especially in OOP style, understand that distinction? But this is just a rhetorical question. Especially since the documentation has already been changed (#13149).
You see, if in the future definitions in errors.h will be given as EXTERN char e_variable_is_something_that_str[], we will get a complete mess. This is probably a problem of all projects when new changes are introduced into old code.
That's why I would suggest you to change the definitions in errors.h and, accordingly, in other code places where they occur, and leave the code itself unchanged where there are no such messages.
I'm going to try to make this :s/member/variable/g now, while I have time.
Translated with www.DeepL.com/Translator (free version)
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@errael
Take a look, please. #13155
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I think past error codes that are older than a few months should never be changed. I think vast majority of users other than the few of us on this thread would much rather that they can find the error code on StackOverflow / Google than the fact that they fulfill some organizational scheme.
Speaking of translators, do we actually have a cohesive way to notify translators of new/modified messages? I am aware that this question extends more than just error codes, but I would imagine a lot of recent additions are indeed error messages that need to be translated. The way it currently works seems kind of ad-hoc and per locale where each translator has their own way of working and frequently falling into bitrot, but I'm not too involved in this. Other apps sometimes use dedicated platforms to track localization effort.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I've sketched out some guidelines for composing messages in Vim. Please excuse my English. It is possible that the meaning of some phrases may be lost because of it.
Error messages and warnings are what help the user to better interact with the program. To better compose error messages, it is recommended to follow the following rules:
1.1. Messages should be concise.
1.2. Messages start with a capital letter like any sentence. No period should be placed at the end of the message.
1.3. Messages should clearly describe where and what just happened.
_Example. E7000: Command :cd cannot change directory_
1.4. Messages should contain an indication of the reason for what happened (unless it contradicts point 1).
_Example. E7000: Command :cd cannot change directory. Buffer is modified_
1.5. The messages should provide recommendations to the user on how to eliminate the cause of the event (if it does not contradict clause 1).
_Example. E7000: Command :cd cannot change directory. Buffer is modified. Add ! to override_
If the message contains names of commands, functions, special characters used in Vim editor, etc., they must be written according to the following rules:
2.1. The names of Vim data types are written with an uppercase letter and are not enclosed in quotation marks.
_Example. E7000: In function support data types List, BLOB, Dictionary_
2.2. Names of functions, methods, classes, objects, interfaces are enclosed in double quotes.
_Example. E7000: In function "len" support data type List, BLOB, Dictionary_
To discuss. In error messages, functions are often specified as FunName(). Should it be enclosed in quotes in this case? As I understand, any programmer will immediately realize that these are function names (and I, not a programmer, can guess what they are). In my opinion, it is not necessary to enclose in quotes in this case.
2.3. Variable names are enclosed in double quotes.
_Example. E7000: Command :unlet cannot delete variable "var1"_
2.4. The names of Vim commands and user-defined commands are written without abbreviations and are indicated with a colon before their names, and are not enclosed in quotation marks.
To discuss. In the documentation, command names are now framed with backquote characters. Perhaps we should do the same in messages to maintain consistency with the documentation and make it easier for the user to find help.
2.5. Parameters (arguments) of Vim commands and user-defined commands are enclosed in double quotes.
2.6. Options and their flags (parameters) are enclosed in single quotes.
2.7. ASCII characters are enclosed in single quotes or specified in words.
**Note. Characters are always specified in word when there is a possibility of their ambiguous interpretation.**
_Example. E7000: In the option 'abcd', the flags '<' and '|' are separated by a comma character_
2.8 Vim or gVim program start arguments are specified with a preceding hyphen-minus character and are not enclosed in quotation marks.
2.9 Symbols of mathematical, logical and bitwise operations are specified as is or in words and are not enclosed in quotation marks.
2.10. The metasymbols of regular expressions are enclosed in single quotes.
2.11. VimL (Vim9) programming language keywords are enclosed in double quotes.
2.12. Names of single keyboard keys are written in capital letters and enclosed in angle brackets.
2.13. In key combinations, key modifiers (<CTRL>, <ALT>, <SHIFT>, <META>) are written in capital letters and are not enclosed in quotation marks or angle brackets.
2.14. Names of Vim events are written in the so-called "Pascal style" and are not enclosed in quotation marks.
2.15. The names of special Vim command line symbols are written in lowercase letters and enclosed in angle brackets.
The definitions of arrays defined in errors.h file and containing messages are compiled according to the following recommendations:
3.1. Array names are written in the so-called "snake style".
3.2. The first letter in the name indicates the kind of message:
e_ - error;
m_ - message;
w_ - warning.
3.3. The array name itself should be a short summary of the message and convey its essence.
3.4. If format specifiers are used in the message, the array name must specify the type of substituted data for each format specifier.
_Example. EXTERN char e_argument_nr_type_mismatch_expected_str_but_got_str[]_
_E1013: Argument %d: type mismatch, expected %s but got %s_
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Perhaps future codes can and should be grouped?
The question is by what principle to group the messages.
Is it worth making groups for each Vim command (function). Or should they be grouped by data types, or by Vim modes?
In my opinion, a good starting point would be the features available in the editor combined with the already existing categorization for built-in functions.
But whichever variant is adopted, there should necessarily be separate groups, it seems to me, for cases that don't fall under any of the criteria (and there are and will be such messages) and a group for internal Vim errors.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I would probably prefer to say that names of keys are written using :help key-notation and names of datatypes are written as they appear in :help variables. Generally, be consistent with what we see elsewhere in documentation.
—
Reply to this email directly, view it on GitHub,.
You are receiving this because you commented.![]()
About grouping errors together numerically.
Especially after the mention of stack overflow and users catching number; by this time, most users wouldn't be able to tell anything from the code value (unless it's one they see a lot).
The main beneficiary of grouping might be the developers looking for messages about a particular issue.
—
Reply to this email directly, view it on GitHub,.
You are receiving this because you commented.![]()
Agree with this. I think the vast majority of users aren't going to be able to tell what the numbering scheme is, nor do I particularly think it's important. The importance of the number is to provide a unique and quick way to identify a problem and to look it up.Humans are bad at numbers in general and using it as a namespacing scheme seems like a nice-to-have at best. I do think it's useful to try to allocate a range if we can plan ahead, but it's mostly for Vim developers, not users. In general, descriptive error message/documentation are much more useful to the end-user on the receiving end of an error.
Think about compilers with warning/error numbers. I really double a C++ programmer (e.g. me) would notice or care that Visual Studio warnings C4839 and C4840 happen to both relate to "non-portable use of class 'type'". It's nice they are grouped together but I'm just going to Google it if the explanation doesn't make sense to me.
If the type of error is so important, I think we could namespace them properly with something like "E-V1234" for Vimscript error, "E-X5678" for Ex error, etc. I'm not sure if it's necessary though.
—
Reply to this email directly, view it on GitHub,.
You are receiving this because you commented.![]()