Easily turn Nushell modules into cross-shell CLI tools
library
nu
nushell
1#!/usr/bin/env nu
2# SPDX-License-Identifier: AGPL-3.0-only
3# Copyright (c) 2026 MatrixFurry <matrix@matrixfurry.com>
4
5const module_path: path = "@MODULE_PATH@"
6const module_name = $module_path | path basename
7const print_usage = @PRINT_USAGE@
8
9use std log
10use $module_path
11
12def main --wrapped [
13 # TODO: --choose (-c) # Interactively choose a function
14 --help (-h)
15 --list (-l) # List available commands
16 --list-all # List all available commands, including hidden ones
17 --interactive (-i) # Enter interactive shell with the module loaded
18 ...cmd
19] {
20 if $interactive {
21 exec nu -e $"use ($module_path); print '(ansi yellow)Module loaded.(ansi reset)'"
22 } else if $list_all {
23 print-functions --all
24 } else if $help or $list or ($cmd | length) == 0 {
25 print-functions
26 } else {
27 let cmd_str = $cmd | str join ' '
28 let function = get-functions | where ($cmd_str starts-with $it) | first
29
30 if ($function | is-empty) {
31 log error $"Unknown command: `($cmd_str)`"
32 print-functions
33 exit 1
34 }
35
36 exec nu -c $"use ($module_path); ($module_name) ($cmd_str)"
37 }
38}
39
40def get-functions [] {
41 scope modules
42 | where name == $module_name
43 | get 0.commands.name
44}
45
46def print-functions [
47 --all (-a) # show hidden functions
48] {
49 get-functions
50 | if $all {$in} else {$in | where $it not-starts-with "_"}
51 | each {|function|
52 let help = help $module_name $function | lines
53
54 let short_description = $help
55 | first
56 | if $in == $"(ansi green)Usage(ansi reset):" {
57 null
58 } else {
59 $in
60 }
61
62 mut table = {
63 command: $"(ansi cyan)($function)(ansi reset)"
64 description: $"(ansi lp)($short_description)(ansi reset)"
65 }
66
67 if $print_usage {
68 let usage = $help
69 | get (
70 ($help | enumerate | where item == $"(ansi green)Usage(ansi reset):").0.index + 1
71 )
72 | str trim
73
74 $table = $table | merge {usage: $usage}
75 }
76
77 $table
78 }
79 | table --index false --theme rounded
80}
81