-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Add basic support for nushell (including on Windows) #58413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Replace regex with explicit replace. Remove @static macro and use `Sys.iswindows()` instead Co-authored-by: Jakob Nybo Nissen <[email protected]>
base/client.jl
Outdated
@static if !Sys.iswindows() | ||
if shell_name == "nu" | ||
# remove backticks and apostrophes that dont play nice with nushell | ||
shell_escape_cmd = replace(shell_escape(cmd), "'" => "", "`" => "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with nushell, but how does this not change the argument semantics?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like mainly it makes them wrong. You're supposed to parse the cmd string with special=Base.shell_special
if you want this behavior, and the REPL does not (currently) do that, so it is expected (currently) to output the string instead unchanged:
shell> echo hi | cat
hi | cat
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback! I'm not sure I fully understand your comment, but I will do my best to respond.
It looks like removing backticks was a mistake by me, and is actually not required (i've update that), but removing apostrophes seems to be required.
If I change to the following:
if shell_name == "nu"
println("just shell_escape(cmd):\t", shell_escape(cmd))
shell_escape_cmd = shell_escape(cmd)
shell_escape_cmd = "try { $shell_escape_cmd } catch { |err| \$err.rendered }"
cmd = `$shell -c $shell_escape_cmd`
# ...
Then most examples work well, except when the cmd contains "
or $
.
Here are 2 examples:
shell> let x = 5; print \$\"The value of x is (\$x)\"
just shell_escape(cmd): let x = 5; print '$"The' value of x is '($x)"'
$"The
value
of
x
is
($x)"
shell> \"hello\" | save test.txt -f
just shell_escape(cmd): '"hello"' | save test.txt -f
shell> open test.txt
just shell_escape(cmd): open test.txt
"hello"
whereas in nushell, what we would be expecting is
> let x = 5; print $"The value of x is ($x)"
The value of x is 5
> "hello" | save test.txt -f
> open test.txt
hello
If there is a better way to achieve this result, please let me know and I will try and amend it :)
base/client.jl
Outdated
if shell_name == "nu" | ||
# remove apostrophes that dont play nice with nushell | ||
shell_escape_cmd = replace(shell_escape(cmd), "'" => "") | ||
shell_escape_cmd = "try { $shell_escape_cmd } catch { |err| \$err.rendered }" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the try-catch needed? Since it is being run with nu -c
I thought it would already translate the error to the base shell, no?
(We do want to propagate errors, no? I thought the bash && true
was just to normalise success to exit code 0 without masking real errors)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think nushell is a bit better at normalising errors already, so maybe this line could be deleted?
(I think the "'" replacement makes sense though. Although I do kind of worry if Cmd
itself is going to limit nushell compat. Would be better if repl_cmd
took the raw string as input.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback! I added it to try make it analogous to the && true
, but yeah I think you are right. I've removed it and looks like everything is still working as expected :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Keno @vtjnash @jakobnissen would it be alright if repl_cmd
is fed cmd::Cmd
and also a new raw_input::String
input? That way, shells that are not bash-like would have access to the raw input. It also means that nushell would be able to properly use piped commands without being turned into string '|'
.
I can submit a fork of this PR with a possible way of doing this
nushell can handel errors and carry on without it
I guess that since #58554 has been merged that this PR is no longer of interest to the team and should be closed? |
I really don’t know. The windows shell support issue was closed as not planned, though it seems there was not a clear consensus among Julia maintainers, as some of them had given a +1 to Windows support. At present it seems we have this awkward asymmetry between operating systems, where unix runs with The unix mode fixes this, because it forwards commands to a proper shell. But Windows mode does not. I think I would personally prefer one the options here: #58525 (comment) |
@sandyspiers perhaps you could rebase your PR and make it simply do the following instead? - if !Sys.iswindows()
+ if !Sys.iswindows() || shell in ("nu", "powershell") since those shells have multi-platform support and also work with the I can’t say I love the special casing though. Letting packages handle this instead via some sort of hook would probably be best. But I think it gets things working at least |
The problem with powershell, is we don't have a safe-quoting algorithm to make it safe to pass user data to it. There are numerous open issues on the powershell repo that their safe-quote algorithm is unsound, so I don't know that julia can encourage use of it programmatically. I don't know quoting rules for nushell to make any comments about its usability. |
Totally get that! I think the best approach for Julia itself is to just make this configurable. Then we don't have to bother core maintainers to support Windows in shell mode (and wait for the next release cycle for fixes), we can just tweak it ourselves with a package. I think it is fine to have a sensible default like All I ask for... is a hook 🙏 |
This PR adds basic support for Nushell in shell mode. Should fix #54291.
I have also added this capability for Windows systems, although I know there is a long and ongoing discussion about how best to support shell-model on Windows (see #23597), so I'm happy to leave this out of the PR if that's preferred. However, I am getting exactly the same functionality on Linux and Windows :)
Here are some examples:
Linux
Windows
Limitations: Nushell is not POSIX-compliant, so there are some characters that the user must escape manually in order for them to carry through the Julia backtick syntax and
shell_escape(...)
function. As far as I can tell, the only times a user might came across this is for'
,"
and$
. The obvious workaround is to just escape them:Thanks!