Skip to content

Commit e220b9d

Browse files
committed
Highlight the differences between scripts and modules
1 parent 1dae0c3 commit e220b9d

File tree

2 files changed

+49
-14
lines changed

2 files changed

+49
-14
lines changed

book/modules.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ The `main` is exported only when
186186

187187
Importing definitions selectively (`use greetings.nu hello` or `use greetings.nu [hello hi]`) does not define the `greetings` command from `main`. You can, however, selectively import `main` using `use greetings main` (or `[main]`) which defines _only_ the `greetings` command without pulling in `hello` or `hi`.
188188

189+
Additionally, `main` has special behavior if used in a script file, regardless of whether it is exported or not. See the [section on scripts](scripts.html#parameterizing-scripts) for more details.
190+
189191
Apart from commands (`def`, `def --env`), known externals (`extern`) can also be named `main`.
190192

191193
## Submodules and Subcommands
@@ -197,8 +199,7 @@ Submodules are modules inside modules. They are automatically created when you c
197199

198200
The difference is that `export module some-module` _only_ adds the module as a submodule, while `export use some-module` _also_ re-exports the submodule's definitions. Since definitions of submodules are available when importing from a module, `export use some-module` is typically redundant, unless you want to re-export its definitions without the namespace prefix.
199201

200-
> **Note**
201-
> `module` without `export` defines only a local module, it does not export a submodule.
202+
> **Note** > `module` without `export` defines only a local module, it does not export a submodule.
202203
203204
Let's illustrate this with an example. Assume three files:
204205

@@ -425,10 +426,11 @@ A common pattern in traditional shells is dumping and auto-sourcing files from a
425426
Here we'll create a simple completion module with a submodule dedicated to some Git completions:
426427

427428
1. Create the completion directory
428-
`mkdir ($nu.default-config-dir | path join completions)`
429+
`mkdir ($nu.default-config-dir | path join completions)`
429430
2. Create an empty `mod.nu` for it
430-
`touch ($nu.default-config-dir | path join completions mod.nu)`
431+
`touch ($nu.default-config-dir | path join completions mod.nu)`
431432
3. Put the following snippet in `git.nu` under the `completions` directory
433+
432434
```nu
433435
export extern main [
434436
--version(-v)
@@ -450,17 +452,20 @@ def complete-git-branch [] {
450452
# ... code to list git branches
451453
}
452454
```
455+
453456
4. Add `export module git.nu` to `mod.nu`
454457
5. Add the parent of the `completions` directory to your NU_LIB_DIRS inside `env.nu`
458+
455459
```nu
456460
$env.NU_LIB_DIRS = [
457461
...
458462
$nu.default-config-dir
459463
]
460464
```
465+
461466
6. import the completions to Nushell in your `config.nu`
462-
`use completions *`
463-
Now you've set up a directory where you can put your completion files and you should have some Git completions the next time you start Nushell
467+
`use completions *`
468+
Now you've set up a directory where you can put your completion files and you should have some Git completions the next time you start Nushell
464469

465470
> **Note**
466471
> This will use the file name (in our example `git` from `git.nu`) as the module name. This means some completions might not work if the definition has the base command in its name.
@@ -515,5 +520,4 @@ It can be one of the following:
515520

516521
- Hides all the module's exports, without the prefix
517522

518-
> **Note**
519-
> `hide` is not a supported keyword at the root of a module (unlike `def` etc.)
523+
> **Note** > `hide` is not a supported keyword at the root of a module (unlike `def` etc.)

book/scripts.md

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ greet "world"
2525

2626
A script file defines the definitions for custom commands as well as the main script itself, which will run after the custom commands are defined.
2727

28-
In the above, first `greet` is defined by the Nushell interpreter. This allows us to later call this definition. We could have written the above as:
28+
In the above example, first `greet` is defined by the Nushell interpreter. This allows us to later call this definition. We could have written the above as:
2929

3030
```nu
3131
greet "world"
@@ -75,9 +75,9 @@ def main [x: int] {
7575

7676
## Argument Type Interpretation
7777

78-
By default, arguments provided to a script are interpreted with the type `Type::Any`, implying that they are not constrained to a specific data type and can be dynamically interpreted as fitting any of the available data types during script execution.
78+
By default, arguments provided to a script are interpreted with the type `Type::Any`, implying that they are not constrained to a specific data type and can be dynamically interpreted as fitting any of the available data types during script execution.
7979

80-
In the previous example, `main [x: int]` denotes that the argument x should possess an integer data type. However, if arguments are not explicitly typed, they will be parsed according to their apparent data type.
80+
In the previous example, `main [x: int]` denotes that the argument x should possess an integer data type. However, if arguments are not explicitly typed, they will be parsed according to their apparent data type.
8181

8282
For example:
8383

@@ -103,7 +103,7 @@ Hello string +1
103103

104104
## Subcommands
105105

106-
A script can have multiple sub-commands like `run`, `build`, etc. which allows to execute a specific main sub-function. The important part is to expose them correctly with `def main [] {}`. See more details in the [Custom Command](custom_commands.html#sub-commands) section.
106+
A script's `main` command can have multiple [subcommands](custom_commands.html#subcommands) like `run`, `build`, etc. which allows executing a specific sub-function from the commandline.
107107

108108
For example:
109109

@@ -117,17 +117,46 @@ def "main build" [] {
117117
print "building"
118118
}
119119
120-
# important for the command to be exposed to the outside
121-
def main [] {}
120+
def main [] {
121+
print "hello from myscript!"
122+
}
122123
```
123124

124125
```nu
126+
> nu myscript.nu
127+
hello from myscript!
125128
> nu myscript.nu build
126129
building
127130
> nu myscript.nu run
128131
running
129132
```
130133

134+
[Unlike modules](modules.html#main), `main` does _not_ need to exported in order to be visible. In the above example, our `main` command is not `export def`, however it was still executed when running `nu myscript.nu`. If we had used myscript as a module by running `use myscript.nu`, rather than running `myscript.nu` as a script, trying to execute the `myscript` command would not work since `myscript` is not exported.
135+
136+
It is important to note that you must define a `main` command in order for subcommands of `main` to be correctly exposed. For example, if we had just defined the `run` and `build` subcommands, they wouldn't be accessible when running the script:
137+
138+
```nu
139+
# myscript.nu
140+
def "main run" [] {
141+
print "running"
142+
}
143+
144+
def "main build" [] {
145+
print "building"
146+
}
147+
```
148+
149+
```nu
150+
> nu myscript.nu build
151+
> nu myscript.nu run
152+
```
153+
154+
This is a limitation of the way scripts are currently processed. If your script only has subcommands, you can add an empty `main` to expose the subcommands, like so:
155+
156+
```nu
157+
def main [] {}
158+
```
159+
131160
## Shebangs (`#!`)
132161

133162
On Linux and macOS you can optionally use a [shebang](<https://en.wikipedia.org/wiki/Shebang_(Unix)>) to tell the OS that a file should be interpreted by Nu. For example, with the following in a file named `myscript`:
@@ -141,7 +170,9 @@ On Linux and macOS you can optionally use a [shebang](<https://en.wikipedia.org/
141170
> ./myscript
142171
Hello World!
143172
```
173+
144174
For script to have access to standard input, `nu` should be invoked with `--stdin` flag:
175+
145176
```nu
146177
#!/usr/bin/env -S nu --stdin
147178
echo $"stdin: ($in)"

0 commit comments

Comments
 (0)