Skip to content

Commit 6265214

Browse files
authored
Fix nushell with --nom, make shell bits templated (#62)
The nu template uses the executable very differently from others, so it ends up trying weird things like `which nix-your-shell --nom`, which fails because `which` doesn't understand `--nom`. The other shell templates are also broken as shell _scripts_, because they rely on the `nix-your-shell` -> `nix-your-shell $shell` substitution. Fix everything by using a real template engine.
1 parent f2af0f9 commit 6265214

File tree

8 files changed

+75
-37
lines changed

8 files changed

+75
-37
lines changed

Cargo.lock

+40
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ calm_io = "0.1.1"
1616
camino = "1.1.4"
1717
clap = { version = "4.3.4", features = ["derive", "wrap_help", "env"] }
1818
color-eyre = "0.6.2"
19+
minijinja = { version = "1.0.12", features = ["json"] }
1920
shell-words = "1.1.0"
2021
tracing = { version = "0.1.39", features = ["attributes"] }
2122
tracing-subscriber = { version = "0.3.17", features = ["env-filter", "registry"] }

data/env.fish data/env.fish.j2

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
# nix-your-shell | source
33

44
function nix-shell --description "Start an interactive shell based on a Nix expression"
5-
nix-your-shell nix-shell -- $argv
5+
{{ executable }} {{ extra_args | join(" ") }} fish nix-shell -- $argv
66
end
77

88
function nix --description "Reproducible and declarative configuration management"
9-
nix-your-shell nix -- $argv
9+
{{ executable }} {{ extra_args | join(" ") }} fish nix -- $argv
1010
end

data/env.nu data/env.nu.j2

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
# nix-your-shell nu | save nix-your-shell.nu
33

44
def _nix_your_shell (command: string, args: list<string>) {
5-
if not (which nix-your-shell | is-empty) {
5+
if not (which {{ executable }} | is-empty) {
6+
{%- if extra_args %}
7+
{#- If you squint hard enough, JSON lists are just Nu lists #}
8+
let args = {{ extra_args | tojson }} ++ ["--"] ++ $args
9+
{%- else %}
610
let args = ["--"] ++ $args
7-
run-external nix-your-shell $command ...$args
11+
{%- endif %}
12+
run-external {{ executable }} $command ...$args
813
} else {
914
run-external $command ...$args
1015
}

data/env.sh data/env.sh.j2

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
# nix-your-shell | source /dev/stdin
33

44
function nix-shell () {
5-
nix-your-shell nix-shell -- "$@"
5+
{{ executable }} {{ extra_args | join(" ") }} {{ shell }} nix-shell -- "$@"
66
}
77

88
function nix () {
9-
nix-your-shell nix -- "$@"
9+
{{ executable }} {{ extra_args | join(" ") }} {{ shell }} nix -- "$@"
1010
}

data/env.xsh

-5
This file was deleted.

data/env.xsh.j2

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# If you see this output, you probably forgot to pipe it into `source`:
2+
# nix-your-shell | source
3+
4+
aliases['nix-shell'] = '{{ executable }} {{ extra_args | join(" ") }} xonsh nix-shell -- @($args)'
5+
aliases['nix'] = '{{ executable }} {{ extra_args | join(" ") }} xonsh nix -- @($args)'

src/main.rs

+18-26
Original file line numberDiff line numberDiff line change
@@ -93,21 +93,21 @@ fn main() -> eyre::Result<()> {
9393

9494
match opts.command.unwrap_or_default() {
9595
Command::Env => {
96-
let mut shell_code = match shell.kind {
96+
let template = match shell.kind {
9797
ShellKind::Zsh | ShellKind::Bash => {
98-
include_str!("../data/env.sh")
98+
include_str!("../data/env.sh.j2")
9999
}
100100

101101
ShellKind::Fish => {
102-
include_str!("../data/env.fish")
102+
include_str!("../data/env.fish.j2")
103103
}
104104

105105
ShellKind::Nushell => {
106-
include_str!("../data/env.nu")
106+
include_str!("../data/env.nu.j2")
107107
}
108108

109109
ShellKind::Xonsh => {
110-
include_str!("../data/env.xsh")
110+
include_str!("../data/env.xsh.j2")
111111
}
112112

113113
ShellKind::Other(shell) => {
@@ -116,31 +116,23 @@ fn main() -> eyre::Result<()> {
116116
))
117117
.note("Supported shells are: `zsh`, `fish`, `nushell`, `xonsh`, and `bash`")
118118
}
119-
}
120-
.to_owned();
121-
122-
// Do some string replacements to reflect the arguments passed to `nix-your-shell` in
123-
// the generated code.
124-
//
125-
// We could make this a bit "cleaner" with an actual templating language, but it's nice
126-
// that the snippets in `../data/` are valid code and not templates.
127-
128-
let mut shell_args = shell_words::quote(shell.path.as_str());
129-
130-
if opts.nom {
131-
shell_args += " --nom";
132-
}
133-
134-
shell_code =
135-
shell_code.replace("nix-your-shell", &format!("nix-your-shell {}", shell_args));
119+
};
136120

137121
let current_exe =
138122
current_exe().wrap_err("Unable to determine absolute path of `nix-your-shell`")?;
139-
if opts.absolute || !executable_is_on_path(&current_exe)? {
140-
shell_code = shell_code.replace("nix-your-shell", current_exe.as_str());
141-
}
142123

143-
let _ = println!("{shell_code}");
124+
let formatted = minijinja::render!(
125+
template,
126+
executable => if opts.absolute || !executable_is_on_path(&current_exe)? {
127+
current_exe.as_str()
128+
} else {
129+
"nix-your-shell"
130+
},
131+
extra_args => if opts.nom { vec!["--nom"] } else { vec![] },
132+
shell => shell.path.as_str(),
133+
);
134+
135+
let _ = println!("{formatted}");
144136
Ok(())
145137
}
146138

0 commit comments

Comments
 (0)