You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Highlight the differences between scripts and modules (#1567)
* Highlight the differences between scripts and modules
* Change bespoke note to a tip
* Address review notes
Co-authored-by: Douglas <[email protected]>
---------
Co-authored-by: Douglas <[email protected]>
Copy file name to clipboardExpand all lines: book/modules.md
+66-51Lines changed: 66 additions & 51 deletions
Original file line number
Diff line number
Diff line change
@@ -78,11 +78,12 @@ then
78
78
79
79
The result should be similar as in the previous section.
80
80
81
-
> **Note**
82
-
> that the `use greetings.nu hello` call here first implicitly creates the `greetings` module,
83
-
> then takes `hello` from it. You could also write it as `module greetings.nu`, `use greetings hello`.
84
-
> Using `module` can be useful if you're not interested in any definitions from the module but want to,
85
-
> e.g., re-export the module (`export module greetings.nu`).
81
+
::: tip Note
82
+
Note that the `use greetings.nu hello` call here first implicitly creates the `greetings` module,
83
+
then takes `hello` from it. You could also write it as `module greetings.nu`, `use greetings hello`.
84
+
Using `module` can be useful if you're not interested in any definitions from the module but want to,
85
+
e.g., re-export the module (`export module greetings.nu`).
86
+
:::
86
87
87
88
## Modules from Directories
88
89
@@ -112,7 +113,7 @@ then
112
113
113
114
The name of the module follows the same rule as module created from a file: Stem of the directory name, i.e., the directory name, is used as the module name. Again, you could do this as a two-step action using `module` and `use` separately, as explained in the previous section.
114
115
115
-
::: tip
116
+
::: tip Note
116
117
You can define `main` command inside `mod.nu` to create a command named after the module directory.
117
118
:::
118
119
@@ -186,6 +187,8 @@ The `main` is exported only when
186
187
187
188
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`.
188
189
190
+
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.
191
+
189
192
Apart from commands (`def`, `def --env`), known externals (`extern`) can also be named `main`.
190
193
191
194
## Submodules and Subcommands
@@ -197,8 +200,9 @@ Submodules are modules inside modules. They are automatically created when you c
197
200
198
201
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.
199
202
200
-
> **Note**
201
-
> `module` without `export` defines only a local module, it does not export a submodule.
203
+
::: tip Note
204
+
`module` without `export` defines only a local module, it does not export a submodule.
205
+
:::
202
206
203
207
Let's illustrate this with an example. Assume three files:
204
208
@@ -425,58 +429,68 @@ A common pattern in traditional shells is dumping and auto-sourcing files from a
425
429
Here we'll create a simple completion module with a submodule dedicated to some Git completions:
3. Put the following snippet in `git.nu` under the `completions` directory
432
-
```nu
433
-
export extern main [
434
-
--version(-v)
435
-
-C: string
436
-
# ... etc.
437
-
]
438
-
439
-
export extern add [
440
-
--verbose(-v)
441
-
--dry-run(-n)
442
-
# ... etc.
443
-
]
444
-
445
-
export extern checkout [
446
-
branch: string@complete-git-branch
447
-
]
448
-
449
-
def complete-git-branch [] {
450
-
# ... code to list git branches
451
-
}
452
-
```
440
+
441
+
```nu
442
+
export extern main [
443
+
--version(-v)
444
+
-C: string
445
+
# ... etc.
446
+
]
447
+
448
+
export extern add [
449
+
--verbose(-v)
450
+
--dry-run(-n)
451
+
# ... etc.
452
+
]
453
+
454
+
export extern checkout [
455
+
branch: string@complete-git-branch
456
+
]
457
+
458
+
def complete-git-branch [] {
459
+
# ... code to list git branches
460
+
}
461
+
```
462
+
453
463
4. Add `export module git.nu` to `mod.nu`
454
464
5. Add the parent of the `completions` directory to your NU_LIB_DIRS inside `env.nu`
455
-
```nu
456
-
$env.NU_LIB_DIRS = [
457
-
...
458
-
$nu.default-config-dir
459
-
]
460
-
```
461
-
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
464
465
465
-
> **Note**
466
-
> 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.
467
-
> For example, if you defined our known externals in our `git.nu` as `export extern 'git push' []`, etc. and followed the rest of the steps, you would get subcommands like `git git push`, etc.
468
-
> You would need to call `use completions git *` to get the desired subcommands. For this reason, using `main` as outlined in the step above is the preferred way to define subcommands.
466
+
```nu
467
+
$env.NU_LIB_DIRS = [
468
+
...
469
+
$nu.default-config-dir
470
+
]
471
+
```
472
+
473
+
6. Import the completions to Nushell in your `config.nu`:
474
+
475
+
`use completions *`
476
+
477
+
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.
478
+
479
+
::: tip Note
480
+
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.
481
+
For example, if you defined our known externals in our `git.nu` as `export extern 'git push' []`, etc. and followed the rest of the steps, you would get subcommands like `git git push`, etc.
482
+
You would need to call `use completions git *` to get the desired subcommands. For this reason, using `main` as outlined in the step above is the preferred way to define subcommands.
483
+
:::
469
484
470
485
### Setting environment + aliases (conda style)
471
486
472
487
`def --env` commands, `export-env` block and aliases can be used to dynamically manipulate "virtual environments" (a concept well known from Python).
473
488
474
-
We use it in our official virtualenv integrationhttps://github.com/pypa/virtualenv/blob/main/src/virtualenv/activation/nushell/activate.nu
489
+
We use it in our [official virtualenv integration](https://github.com/pypa/virtualenv/blob/main/src/virtualenv/activation/nushell/activate.nu). Another example is our [unofficial Conda module](https://github.com/nushell/nu_scripts/blob/main/modules/virtual_environments/conda.nu).
475
490
476
-
Another example could be our unofficial Conda module: https://github.com/nushell/nu_scripts/blob/f86a060c10f132407694e9ba0f536bfe3ee51efc/modules/virtual_environments/conda.nu
477
-
478
-
> **Warning**
479
-
> Work In Progress
491
+
::: warning
492
+
Work in progress
493
+
:::
480
494
481
495
## Hiding
482
496
@@ -515,5 +529,6 @@ It can be one of the following:
515
529
516
530
- Hides all the module's exports, without the prefix
517
531
518
-
> **Note**
519
-
> `hide` is not a supported keyword at the root of a module (unlike `def` etc.)
532
+
:::tip Note
533
+
`hide` is not a supported keyword at the root of a module (unlike `def` etc.)
Copy file name to clipboardExpand all lines: book/scripts.md
+39-8Lines changed: 39 additions & 8 deletions
Original file line number
Diff line number
Diff line change
@@ -25,7 +25,7 @@ greet "world"
25
25
26
26
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.
27
27
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:
29
29
30
30
```nu
31
31
greet "world"
@@ -75,9 +75,9 @@ def main [x: int] {
75
75
76
76
## Argument Type Interpretation
77
77
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.
79
79
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.
81
81
82
82
For example:
83
83
@@ -103,9 +103,7 @@ Hello string +1
103
103
104
104
## Subcommands
105
105
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.
107
-
108
-
For example:
106
+
A script can have multiple [subcommands](custom_commands.html#subcommands), like `run` or `build` for example:
109
107
110
108
```nu
111
109
# myscript.nu
@@ -117,17 +115,48 @@ def "main build" [] {
117
115
print "building"
118
116
}
119
117
120
-
# important for the command to be exposed to the outside
121
-
def main [] {}
118
+
def main [] {
119
+
print "hello from myscript!"
120
+
}
122
121
```
123
122
123
+
You can then execute the script's subcommands when calling it:
124
+
124
125
```nu
126
+
> nu myscript.nu
127
+
hello from myscript!
125
128
> nu myscript.nu build
126
129
building
127
130
> nu myscript.nu run
128
131
running
129
132
```
130
133
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
+
131
160
## Shebangs (`#!`)
132
161
133
162
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/
141
170
> ./myscript
142
171
Hello World!
143
172
```
173
+
144
174
For script to have access to standard input, `nu` should be invoked with `--stdin` flag:
0 commit comments