Skip to content
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

Support nushell #109

Closed
andrewbanchich opened this issue Aug 21, 2022 · 22 comments
Closed

Support nushell #109

andrewbanchich opened this issue Aug 21, 2022 · 22 comments

Comments

@andrewbanchich
Copy link

After setting nushell as my default shell, I don't think exec-path-from-shell is working correctly.

The output of (getenv "PATH") looks like ${PATH-kj1h2k34jh2kj3h4234}.

@purcell
Copy link
Owner

purcell commented Aug 22, 2022

Try enabling exec-path-from-shell-debug, then you should get more detailed info about what's happening. (In *Messages*, iirc.)

@andrewbanchich
Copy link
Author

The first line is:

Invoking shell /Users/banchich/.cargo/bin/nu with args ("-l" "-i" "-c" "/usr/bin/printf '__RESULT\\000%s\\000%s\\000__RESULT' \"${PATH-1e96998a18bbe92595e1bcb372301ea1}\" \"${MANPATH-1e96998a18bbe92595e1bcb372301ea1}\"")

Then several errors about various programs not being found.

@purcell
Copy link
Owner

purcell commented Aug 22, 2022

Then several errors about various programs not being found.

Which programs?

The intention here is that for non-posix shells like fish and nu, the shell is told to invoke printf in order to print out the env var values in a reliably parseable format. If nu would require the command to be passed in a different way, let me know.

@andrewbanchich
Copy link
Author

Git, for example.

Yeah, getting an equivalent path string from nu would be: $env.PATH | str collect ":"

@purcell
Copy link
Owner

purcell commented Aug 22, 2022

Git, for example.

Ah right. The debug output should also display what nu printed when asked to run that command. It would be helpful if you included that too.

Yeah, getting an equivalent path string from nu would be: $env.PATH | str collect ":"

I know there are shell-specific ways of doing things, but I'm asking about how to run that printf command. Otherwise, for newfangled shells I'd need to parse all sorts of different output, and it has to all work even if there are nulls or newlines etc. in the env var values. The printf method ensures this works the same everywhere.

@andrewbanchich
Copy link
Author

andrewbanchich commented Aug 22, 2022

Output related to git:

Error: (file-missing "Searching for program" "No such file or directory" "git")

I assume that's because exec-path-from-shell thinks the output was a correct $PATH even though it wasn't?

I'm asking about how to run that printf command

Ah, gotcha! printf should just work normally. I tried:

❯ nu -l -i -c 'printf "hello"'
hello

@purcell
Copy link
Owner

purcell commented Aug 26, 2022

I think this should be resolved by dff9ce3.

@andrewbanchich
Copy link
Author

Hmm, I updated and (getenv "PATH") is still giving me the wrong path.

@andrewbanchich
Copy link
Author

andrewbanchich commented Aug 26, 2022

I tried clearing my local package repos and setting nu as the default shell again. Now when Emacs starts I get:

Warning (initialization): An error occurred while loading ‘/Users/banchich/.emacs’:

error: Non-zero exit code from shell /Users/banchich/.cargo/bin/nu invoked with args ("-l" "-i" "-c" "sh -c /usr/bin/printf\\ \\'__RESULT\\\\000\\%s\\\\000\\%s\\\\000__RESULT\\'\\ \\\"\\$\\{PATH-865eec1ee635cce045535a068b81a521\\}\\\"\\ \\\"\\$\\{MANPATH-865eec1ee635cce045535a068b81a521\\}\\\"").  Output was:
"Error: �]8;;https://docs.rs/nu-parser/0.65.0/nu_parser/enum.ParseError.html#variant.UnexpectedEof�\\�[31mnu::parser::unexpected_eof �[0m�[36;1;4m(link)�[0m�]8;;�\\

  �[31m�[0m Unexpected end of code.
   ╭─[�[36;1;4msource�[0m:1:1]
 �[2m1�[0m │ sh -c /usr/bin/printf\\ \\'__RESULT\\\\000\\%s\\\\000\\%s\\\\000__RESULT\\'\\ \\\"\\$\\{PATH-865eec1ee635cce045535a068b81a521\\}\\\"\\ \\\"\\$\\{MANPATH-865eec1ee635cce045535a068b81a521\\}\\\"
   ╰────

"

To ensure normal operation, you should investigate and remove the
cause of the error in your initialization file.  Start Emacs with
the ‘--debug-init’ option to view a complete error backtrace. Disable showing Disable logging

With --debug-init:

Debugger entered--Lisp error: (error "Non-zero exit code from shell /Users/banchich/.cargo/bin/nu invoked with args (\"-l\" \"-i\" \"-c\" \"sh -c /usr/bin/printf\\\\ \\\\'__RESULT\\\\\\\\000\\\\%s\\\\\\\\000\\\\%s\\\\\\\\000__RESULT\\\\'\\\\ \\\\\\\"\\\\$\\\\{PATH-0d51d145bc12...")
  signal(error ("Non-zero exit code from shell /Users/banchich/.cargo/bin/nu invoked with args (\"-l\" \"-i\" \"-c\" \"sh -c..."))
  error("Non-zero exit code from shell %s invoked with args..." "/Users/banchich/.cargo/bin/nu" ("-l" "-i" "-c" "sh -c /usr/bin/printf\\ \\'__RESULT\\\\000\\%s\\\\000\\%s\\...") "Error: \33]8;;https://docs.rs/nu-parser/0.65.0/nu_pa...")
  exec-path-from-shell-printf("%s\\000%s" ("${PATH-0d51d145bc127182e7e7a8ef4d79c309}" "${MANPATH-0d51d145bc127182e7e7a8ef4d79c309}"))
  exec-path-from-shell-getenvs(("PATH" "MANPATH"))
  exec-path-from-shell-copy-envs(("PATH" "MANPATH"))
  exec-path-from-shell-initialize()
  eval-buffer(#<buffer  *load*> nil "/Users/banchich/.emacs" nil t)  ; Reading at buffer position 1968
  load-with-code-conversion("/Users/banchich/.emacs" "/Users/banchich/.emacs" t t)
  load("~/.emacs" noerror nomessage)
  startup--load-user-init-file(#f(compiled-function () #<bytecode -0x1493b59c6f7613b>) #f(compiled-function () #<bytecode -0x1f3c686ddc0d6275>) t)
  command-line()
  normal-top-level()

@purcell
Copy link
Owner

purcell commented Aug 27, 2022

Looks like nu handles escaping completely differently even to other non-standard shells like fish.

Here are the invocations with various shells, with the same command passed each time:

❯ zsh -c "sh -c /etc/profiles/per-user/steve/bin/printf\\ \\'__RESULT\\\\000\\%s\\\\000__RESULT\\'\\ \\\"\\$\\{MANPATH-08ccc6cf287832a08d51789038f15a72\\}\\\""
__RESULT08ccc6cf287832a08d51789038f15a72__RESULT%

fish:

❯ fish -c "sh -c /etc/profiles/per-user/steve/bin/printf\\ \\'__RESULT\\\\000\\%s\\\\000__RESULT\\'\\ \\\"\\$\\{MANPATH-08ccc6cf287832a08d51789038f15a72\\}\\\""
zsh: correct 'fish' to 'vis' [nyae]? n
__RESULT08ccc6cf287832a08d51789038f15a72__RESULT%

nu:

nu -c "sh -c /etc/profiles/per-user/steve/bin/printf\\ \\'__RESULT\\\\000\\%s\\\\000__RESULT\\'\\ \\\"\\$\\{MANPATH-08ccc6cf287832a08d51789038f15a72\\}\\\""
Error: nu::parser::unexpected_eof (link)

  × Unexpected end of code.
   ╭─[source:1:1]
 1 │ sh -c /etc/profiles/per-user/steve/bin/printf\ \'__RESULT\\000\%s\\000__RESULT\'\ \"\$\{MANPATH-08ccc6cf287832a08d51789038f15a72\}\"
   ╰────

Some special case handling would have to be done for nu. Perhaps you could advise? The goal is to print out __RESULT followed by a NULL character, followed by either the env var (if it exists) or the provided hex string (08ccc6cf287832a08d51789038f15a72 in this case), then finally a NULL and __RESULT again.

@andrewbanchich
Copy link
Author

I'll have to get back to you on that - I'm not a nushell expert yet, and can't figure it out myself right now.

Is there a way for exec-path-from-shell users to override that shell command themselves? That way you wouldn't need to handle all the edge cases yourself.

@andrewbanchich
Copy link
Author

andrewbanchich commented Aug 28, 2022

Relevant discussion here: nushell/nushell#6435

@andrewbanchich
Copy link
Author

Looks like the nushell command that will work is $"/usr/bin/printf '__RESULT\u0000%s\u0000__RESULT' \"${MANPATH-08ccc6cf287832a08d51789038f15a72}\"" | sh

@KaranAhlawat
Copy link

@andrewbanchich Did you figure out how to get this working? I see you've shared a snippet, but I'm not sure whete it goes exactly.

@andrewbanchich
Copy link
Author

No I haven't. IIRC there would need to be some update to this package to support it.

@KaranAhlawat
Copy link

Alright, thank you for responding. I've moved away from Nushell for the time being.

purcell added a commit that referenced this issue Apr 10, 2024
@purcell
Copy link
Owner

purcell commented Apr 10, 2024

Okay, you guys nerd-sniped me. Maybe grab the code in #119 and let me know if it works for you?

@purcell
Copy link
Owner

purcell commented Apr 10, 2024

(I figured out that instead of the command above, I could construct a proper nu expression like [ $env."PATH"?, $env."MANPATH"? ] | to json and then read the result from Emacs.)

purcell added a commit that referenced this issue Apr 10, 2024
@KaranAhlawat
Copy link

Okay, you guys nerd-sniped me. Maybe grab the code in #119 and let me know if it works for you?

I'm sorry, that was not my intention. Ideally this shouldn't fall on the maintainer since the shell isn't POSIX(?) compliant.

But also I'm grateful that you did! I'll check it in a bit and update you guys. 😄

@purcell
Copy link
Owner

purcell commented Apr 10, 2024

I'm sorry, that was not my intention. Ideally this shouldn't fall on the maintainer since the shell isn't POSIX(?) compliant.

Don't worry, I got genuinely curious. But I appreciate the sentiment!

purcell added a commit that referenced this issue Apr 11, 2024
@KaranAhlawat
Copy link

Confirmed, it does work from MELPA.

@purcell
Copy link
Owner

purcell commented Apr 11, 2024

Great, thanks @KaranAhlawat!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants