vim9.txt: rewrite Section 2 by kennypete · Pull Request #21132 · vim/vim · GitHub
Skip to content

vim9.txt: rewrite Section 2 - #21132

Open
kennypete wants to merge 3 commits into
vim:masterfrom
kennypete:vim9.txt-Section2
Open

kennypete wants to merge 3 commits into
vim:masterfrom
kennypete:vim9.txt-Section2

Conversation

@kennypete

Copy link
Copy Markdown
Contributor

vim9.txt: Conclusion to the rewrite and enhancements - part 2 of 2 (summary)

This is a very significant update. Initially it considered only Section 2, the last to be enhanced with sourceable Vim9 script examples. Along the way it extended to also include several standardisation changes, plus improvements to some passages of sections 4 and 6 especially. “Part 1” of the rewrite addressed those things in Sections 1, and 3 to 7 (NB: they are listed in the explanation to PR20706).

The description, which follows, is a SUMMARY only.
For more details and the rationale of changes, refer to this Gist: vim9.txt rewrite Section 2 (details).

Some improvements in this “Part 2” update necessarily involve the help files eval.txt and userfunc.txt, where some tags are better relocated either to/from vim9.txt.

Locations of changes are indicated by reference to *tag* in the updated file.

1. Corrections to the current help

  • :&: currently, the help states this, “cannot be used to repeat a :substitute command”. That is incorrect. Only bare & is unusable; :& remains valid.
  • Comparing null with 0/false in legacy script: Currently, the help states this “would return true”. That is incorrect because 1 is not literally true, and legacy Vim script returns 1.
  • Predefined-value type table: The current help states, “the other null_ values have the type indicated by their name”. That is a little misleading. For example, null_partial is v:t_func, not v:t_partial.
  • For-loop item-deletion “trick”: The current help implies this legacy technique does not apply in Vim9 script, which is not wholly the case because it works identically in a non-compiled scope, only behaving differently when compiled.

2. Error codes

Many are relocated, and almost all are accompanied by sourceable scripts now.

  • Nearly every error code, below, previously had no sourceable/working example or sat in a location disconnected from what actually triggers it. Most now have a dedicated, sourceable script demonstrating what gives the error.
    • New or first-time examples: E1004, E1014, E1017, E1020, E1021, E1025, E1026, E1034, E1050, E1054, E1055, E1068, E1069, E1074, E1075, E1079, E1080, E1082, E1084, E1087, E1091, E1097, E1099, E1100, E1103, E1106, E1124, E1127, E1128, E1130, E1131, E1133, E1134, E1139, E1144, E1147, E1148, E1149, E1150, E1157, E1160, E1163, E1167, E1168, E1171, E1172, E1176, E1178, E1180, E1181, E1182, E1190, E1191, E1202, E1205, E1213, E1254, E1307, E1360 (example only added; the tag remains in `vim9class.txt), E1395, E1581.
    • Relocated for logical grouping (i.e., the tag is moved to sit with its actual trigger, rather than a disconnected general list): E1147/E1148 (moved from eval.txt to vim9.txt), E1037 (eval.txt, hot-linked to the new *vim9-comparators*), E1094, E1053, E1071, E1257, E1261, and the E1047–E1262 import/namespace block (12 errors, itemised individually via the companion “Part 1” PR).

3. Other improvements

  • New tags are added for concepts which previously had none: *vim9-invalid-Ex-commands*, *vim9-no-shorten*, *vim9-functions*, *vim9-any-type*, *vim9-block*, *vim9-no-shadowing*, *vim9-omitting-:call*, *vim9-omitting-:eval*, *vim9-noclear*, and more.
  • Legacy Vim versus Vim9 script comparisons are added in places where Vim9 script-only or abstract snippets do/would not clearly demonstrate the script version behavioural differences.
  • The “Predefined values” passage is restructured as a table (type()/typename()/string() per value) rather than prose.
  • The “Comparators” passage expands string-only coverage to complete treatment of primitive types, jobs/channels, containers, Funcrefs, class objects, and enum values (including enum singleton-mutation behaviour), none of which is documented currently.

4. Open questions

  • E1146 (“Command not recognised”): This may be unreachable following resolution of Issues 8454, 8563, and 9270. It has been left as-is, though is worth a maintainer’s view regarding whether either it is now redundant or remains an intentional catch-all.
  • userfunc.txt: The recommendation to prefix autoloaded function calls with g:filename#funcname() appears worthy of revision, though is out of this PR’s scope to change.
  • null_class/null_enumvalue: The former always errors when used as a value with no apparent legitimate use. Conversely, there is no null_enumvalue, despite it seeming as though it could have real utility. It may be worth a design discussion.
  • E1213 placement: Currently this is in Section 2’s shadowing passage. Arguably, this could sit with the Import errors in Section 6.
  • The legacy is/== non-transitivity (v:true == 8 and 8 == 8.0 both work, but v:true == 8.0 errors). This has been documented as an aside because it is outside this PR’s scope to resolve (and given it is in legacy Vim script, probably is not worth messing with, though may be worth considering).

Signed-off-by: Peter Kenny <64727695+kennypete@users.noreply.github.com>
@mao-yining

Copy link
Copy Markdown
Contributor

@kennypete

Copy link
Copy Markdown
Contributor Author

Vimtags check failed. Could you run helptags ++t for doc/?

An identical tags file is produced with that (i.e., to what is in the PR). I even ran it from two Vim instances to see whether it was different. It isn't; all three (pushed, produced with GitBash w/ 9.0.2112 and produced with Win11 gVim 9.2.0993 are verbatim).

@chrisbra

Copy link
Copy Markdown
Member

Vimtags check failed. Could you run helptags ++t for doc/?

An identical tags file is produced with that (i.e., to what is in the PR). I even ran it from two Vim instances to see whether it was different. It isn't; all three (pushed, produced with GitBash w/ 9.0.2112 and produced with Win11 gVim 9.2.0993 are verbatim).

It fails, on this sentence:

  • null_tuple (because |tuples| are immutable, neither adding to nor
    extending them is permitted), and

I believe this is because |tuples| is not a valid help reference, only |tuple| or |Tuples| is.

Signed-off-by: Peter Kenny <64727695+kennypete@users.noreply.github.com>
Signed-off-by: Peter Kenny <64727695+kennypete@users.noreply.github.com>

@chrisbra chrisbra left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First round of review, stopping after Variable declaration

Comment thread runtime/doc/eval.txt
single character (including any composing characters) from expr10. To use
byte indexes use |strpart()|.
- Index zero gives the first byte or character. Careful: text column numbers
start with one!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I am missing something, this describes legacy (byte) and vim9 syntax, so contrary to the In |Vim9| script: at the beginning of the paragraph.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure whether you mean strpart() or the next bullet's "Index zero...". For strpart(), no:

image

For "Index zero...", yes - I should have picked that (and the next one) up. Will update it to:

- Index zero gives the first character (including any composing character).
  Careful: text column numbers start with one!

Comment thread runtime/doc/eval.txt
- If the length of the String is less than the index, the result is an empty
String. A negative index always results in an empty string (reason:
backward compatibility). Use [-1:] to get the last byte or character.
- A negative index is used like with a list: count from the end.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it should be:

Use [-1 :] to get the last character (including
  any composing character).

(It was missing the space before the ] too.)

Comment thread runtime/doc/eval.txt
byte indexes use |strpart()|.
- Index zero gives the first byte or character. Careful: text column numbers
start with one!
- If the length of the String is less than the index, the result is an empty

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a duplicate? These lines all overlap with the two comments' lines above.

Comment thread runtime/doc/eval.txt
backward compatibility). Use [-1:] to get the last byte or character.
- A negative index is used like with a list: count from the end.
- Attempting to assign to or modify a string with an index within a `:def`
function gives |E1148|.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but this seems to be Vim9 specific

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes and no. There is an example at *E1148* in vim9.txt Section 2:
image
(though I'll get rid of that unnecessary call )

The legacy Vim script fails too, though a different error is given:
image

So, 1584-1585 are correct and specific to Vim9 script.

Comment thread runtime/doc/vim9.txt
var ad = {item: 'value', func: DictFunc}
ad.func(ad, 'item')
<
Further, if the functions, above, are subsequently called before the functions

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Further, if the functions, above, are subsequently called before the functions
Further, if the functions, above, are subsequently called before the commands

in the sections around it , we use "commands" when describing DefinedLate1 and DefinedLate2

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good spot. I'll fix that with the next commit.

Comment thread runtime/doc/vim9.txt
enddef
MyFunc(v:none, 'LAST') # first argument uses default value 'one'
echo F(2.0, v:none) # 12.56 (using default 'pi' value, 3.14)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better to re-order the arguments, otherwise the use of v:none looks a bit artificial (as last argument and could be left away), so use this:

vim9script
def F(pi: float = 3.14, ra: float = 3.0): float
  return pi * ra->pow(2)
enddef
echo F(v:none, 2.0)	# 12.56 (using default 'pi' value, 3.14)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair. I wonder about defaulting ra, though overall that's a better example for v:none.

Comment thread runtime/doc/vim9.txt
echo (Function(), Funcref()) # ('two', 'two')
<
Note: This persistent behavior of |funcref()| may be regarded as
either a feature, or, if not understood, be unexpected.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this sounds slightly odd, perhaps better:

Note: This persistent behavior of |funcref()| may be regarded as a feature, or may be unexpected if not understood.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that flows better.

@chrisbra chrisbra left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great re-work. That must have been a lot of work. Thanks

Comment thread runtime/doc/vim9.txt
You cannot use `:va` to declare a variable - it must be `:var`. Similarly,
you cannot use `:cons` or `:fin` for constants - they must be written in full
as `:const` or `:final`, which improves readability. Attempting to use `:va`,
`:cons`, or `:fina` gives |E1065|.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is duplicate to the block above at :h vim9-declaration

Comment thread runtime/doc/vim9.txt
echo $'Digit {d} is "{m}" in Māori.'
<
This approach should be used only where there is a list with values.
Declaring one variable per line usually is easier to read and change later.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Declaring one variable per line usually is easier to read and change later.
Declaring one variable per line usually is easier to understand.

Comment thread runtime/doc/vim9.txt
NAMES[1][0] = "Emma" # OK, now females[0] == "Emma"
The following script shows:
- That a constant must have a value, otherwise E1021 is given, and
- Attempts to change a constant fail, with E1307 given.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Attempts to change a constant fail, with E1307 given.
- Attempts to change a constant fail, with E1307.

Comment thread runtime/doc/vim9.txt
< *vim9-no-shadowing*
Variables, functions and function arguments cannot shadow previously defined
or imported variables and functions in the same script file. However,
variables can shadow Ex commands, though rename the variable if necessary.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
variables can shadow Ex commands, though rename the variable if necessary.
variables can shadow Ex commands, so rename the variable if necessary.

Comment thread runtime/doc/vim9.txt
>vim9
vim9script
# Synonymous with ":glob/delimiter)" (and prints these lines)
:glob(delimiter)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the point your are making here, but the command will throw an error "Pattern not found", unless you want to search for the delimiter) (including the closing paren)

Comment thread runtime/doc/vim9.txt
MyN( 4, 5, 6 ) # [4, 5, 6]
MyN (7, 8, 9) # E492: Not an editor command
<
Note: The following also are not allowed, and would give |E492|: >

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Note: The following also are not allowed, and would give |E492|: >
Note: The following are also not allowed, and give |E492|: >

Comment thread runtime/doc/vim9.txt

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the reason why silent is allowed , is because it allows to swallow error messages when Vim does not support the eval feature, see e.g. defaults.vim
(not sure if you want to add this as an explanation)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants