(A good companion for numd)
dotnu augments Nushell with helpers for literate programming, dependency analysis, and script profiling.

> git clone https://github.com/nushell-prophet/dotnu; cd dotnu
> use dotnu
dotnu
lets you write literate Nushell: ordinary Nushell scripts that include the real command output right after each pipeline ending in | print $in
. See the capture example to grasp the idea quickly.
The | print $in
suffix acts as a simple print
in native Nushell and as a capture marker for dotnu, so scripts remain valid and functional even when run without loading the dotnu
module.
The main command is dotnu embeds-update
.
dotnu embeds-update
takes a script, rewrites every print $in
line so its output is easy to parse, runs the modified script, captures what each marked line prints, and then replaces the old # =>
blocks in the original file with the fresh output.
You can run it on a file path (e.g., dotnu embeds-update dotnu-capture.nu
) or pipe a script into it (e.g., "ls | print $in" | dotnu embeds-update
).
> dotnu embeds-update --help
# => Inserts captured output back into the script at capture points
# =>
# => Usage:
# => > embeds-update {flags} (file)
# =>
# => Flags:
# => --echo: output updates to stdout
# => -h, --help: Display the help message for this command
# =>
# => Parameters:
# => file <path>: (optional)
# =>
# => Input/output types:
# => โญโ#โโฌโโinputโโโฌโoutputโโโฎ
# => โ 0 โ string โ nothing โ
# => โ 1 โ string โ string โ
# => โ 2 โ nothing โ string โ
# => โ 3 โ nothing โ nothing โ
# => โฐโ#โโดโโinputโโโดโoutputโโโฏ
# =>
While it is easy to write scripts in editor, there are several convenience helper commands that facilitate populating script files from terminal.
define or change the capture file (add --auto-commit
to autoโcommit snapshots).
> dotnu embeds-setup --help
# => Set environment variables to operate with embeds
# =>
# => Usage:
# => > embeds-setup {flags} (path)
# =>
# => Flags:
# => --auto-commit
# => -h, --help: Display the help message for this command
# =>
# => Parameters:
# => path <path>: (optional)
# =>
# => Input/output types:
# => โญโ#โโฌโinputโโฌโoutputโโฎ
# => โ 0 โ any โ any โ
# => โฐโ#โโดโinputโโดโoutputโโฏ
# =>
record every result printed in the interactive session.
> dotnu embeds-capture-start --help
# => start capturing commands and their outputs into a file
# =>
# => Usage:
# => > embeds-capture-start (file)
# =>
# => Flags:
# => -h, --help: Display the help message for this command
# =>
# => Parameters:
# => file <path>: (optional, default: 'dotnu-capture.nu')
# =>
# => Input/output types:
# => โญโ#โโฌโโinputโโโฌโoutputโโโฎ
# => โ 0 โ nothing โ nothing โ
# => โฐโ#โโดโโinputโโโดโoutputโโโฏ
# =>
capture only the pipeline you run it on; useful for fineโgrained examples.
> dotnu embed-add --help
# => Embed stdin together with its command into the file
# =>
# => Usage:
# => > embed-add {flags}
# =>
# => Flags:
# => -p, --pipe-further: output input further to the pipeline
# => --published: output the published representation into terminal
# => --dry_run: todo: --
# => -h, --help: Display the help message for this command
# =>
# => Input/output types:
# => โญโ#โโฌโinputโโฌโoutputโโฎ
# => โ 0 โ any โ any โ
# => โฐโ#โโดโinputโโดโoutputโโฏ
# =>
strip all captured output, leaving clean code.
> dotnu embeds-remove --help
# => Removes annotation lines starting with "# => " from the script
# =>
# => Usage:
# => > embeds-remove
# =>
# => Flags:
# => -h, --help: Display the help message for this command
# =>
# => Input/output types:
# => โญโ#โโฌโinputโโฌโoutputโโฎ
# => โ 0 โ any โ any โ
# => โฐโ#โโดโinputโโดโoutputโโฏ
# =>
> dotnu dependencies --help
# => Check .nu module files to determine which commands depend on other commands.
# =>
# => Usage:
# => > dependencies {flags} ...(paths)
# =>
# => Flags:
# => --keep-builtins: keep builtin commands in the result page
# => --definitions-only: output only commands' names definitions
# => -h, --help: Display the help message for this command
# =>
# => Parameters:
# => ...paths <path>: paths to nushell module files
# =>
# => Input/output types:
# => โญโ#โโฌโinputโโฌโoutputโโฎ
# => โ 0 โ any โ any โ
# => โฐโ#โโดโinputโโดโoutputโโฏ
# =>
# => Examples:
# =>
# => > dotnu dependencies ...(glob tests/assets/module-say/say/*.nu)
# => โญโ#โโโฌโโcallerโโโโฌโfilename_of_callerโโโฌโโcalleeโโโโฌโstepโโโฎ
# => โ 0 โ hello โ hello.nu โ โ 0 โ
# => โ 1 โ question โ ask.nu โ โ 0 โ
# => โ 2 โ say โ mod.nu โ hello โ 0 โ
# => โ 3 โ say โ mod.nu โ hi โ 0 โ
# => โ 4 โ say โ mod.nu โ question โ 0 โ
# => โ 5 โ hi โ mod.nu โ โ 0 โ
# => โ 6 โ test-hi โ test-hi.nu โ hi โ 0 โ
# => โฐโ#โโโดโโcallerโโโโดโfilename_of_callerโโโดโโcalleeโโโโดโstepโโโฏ
# =>
> dotnu filter-commands-with-no-tests --help
# => Filter commands after `dotnu dependencies` that aren't used by any other command containing `test` in its name.
# =>
# => Usage:
# => > filter-commands-with-no-tests
# =>
# => Flags:
# => -h, --help: Display the help message for this command
# =>
# => Input/output types:
# => โญโ#โโฌโinputโโฌโoutputโโฎ
# => โ 0 โ any โ any โ
# => โฐโ#โโดโinputโโดโoutputโโฏ
# =>
# => Examples:
# =>
# => > dependencies ...(glob tests/assets/module-say/say/*.nu) | filter-commands-with-no-tests
# => โญโ#โโฌโโcallerโโโฌโfilename_of_callerโโฎ
# => โ 0 โ hello โ hello.nu โ
# => โ 1 โ question โ ask.nu โ
# => โ 2 โ say โ mod.nu โ
# => โฐโ#โโดโโcallerโโโดโfilename_of_callerโโฏ
# =>
dotnu set-x
opens a regular .nu script. It divides it into blocks using the specified regex (by default, it is "\n\n") and generates a new script that will print the code of each block before executing it, along with the timings of each block's execution.
Let's check the code of the simple set-x-demo.nu
script
> let $filename = [tests assets set-x-demo.nu] | path join
> open $filename | lines | table -i false
# => โญโโโโโโโโโโโโโโโฎ
# => โ sleep 0.5sec โ
# => โ โ
# => โ sleep 0.7sec โ
# => โ โ
# => โ sleep 0.8sec โ
# => โฐโโโโโโโโโโโโโโโฏ
Let's see how dotnu set-x
will modify this script
> dotnu set-x $filename --echo | lines | table -i false
# => โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
# => โ mut $prev_ts = ( date now ) โ
# => โ print ("> sleep 0.5sec" | nu-highlight) โ
# => โ sleep 0.5sec โ
# => โ print $'(ansi grey)((date now) - $prev_ts)(ansi reset)'... โ
# => โ โ
# => โ โ
# => โ print ("> sleep 0.7sec" | nu-highlight) โ
# => โ sleep 0.7sec โ
# => โ print $'(ansi grey)((date now) - $prev_ts)(ansi reset)'... โ
# => โ โ
# => โ โ
# => โ print ("> sleep 0.8sec" | nu-highlight) โ
# => โ sleep 0.8sec โ
# => โ print $'(ansi grey)((date now) - $prev_ts)(ansi reset)'... โ
# => โ โ
# => โ โ
# => โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ