zed-industries / zed

Code at the speed of thought – Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.
https://zed.dev
Other
49.61k stars 3.04k forks source link

Zed Terminal opens bash with Raycast, but zsh(default shell) with Spotlight. #8794

Closed thapabishwa-plerionaut closed 6 months ago

thapabishwa-plerionaut commented 8 months ago

Check for existing issues

Describe the bug / provide steps to reproduce it

Zed settings.json

// Zed settings
//
// For information on how to configure Zed, see the Zed
// documentation: https://zed.dev/docs/configuring-zed
//
// To see all of Zed's default settings without changing your
// custom settings, run the `open default settings` command
// from the command palette or from `Zed` application menu.
{
  "theme": {
    "light": "Ayu Light",
    "dark": "Ayu Dark"
  },
  "vim_mode": true,
  "ui_font_size": 16,
  "buffer_font_size": 16,
  "terminal": {
    "blinking": "terminal_controlled",
    "copy_on_select": false,
    "working_directory": "current_project_directory"
  },
  "format_on_save": "on",
  "lsp": {
    "gopls": {
      "initialization_options": {
        "gofumpt": true
      }
    }
  }
}

Video:

https://github.com/zed-industries/zed/assets/124118626/c35661f4-cb05-4189-ad78-2cecf6c1b5a0

Environment

MacBook Pro 13-inch, M2, 2022 Chip: M2 Memory: 16 GB

If applicable, add mockups / screenshots to help explain present your vision of the feature

No response

If applicable, attach your ~/Library/Logs/Zed/Zed.log file to this issue.

If you only need the most recent lines, you can run the zed: open log command palette action to see the last 1000.

No response

Moshyfawn commented 8 months ago

The default shell to open in Zed is set to "system". What happens if you change it to one of your preferred shells?

{
  "terminal": {
    "shell": {
      "program": "zsh"
    }
  }
}
thapabishwa-plerionaut commented 8 months ago

Hey @Moshyfawn, my default shell is /bin/zsh. I was confused when Zed opened bash even when SHELL was set to /bin/zsh.

I see the following with raycast only. Spotlight works fine with the config you suggested.

image

mrnugget commented 8 months ago

Hey there! Few questions to try to nail this down:

  1. What happens if you open it by clicking on Zed.app in /Applications?
  2. And what happens if you launch it via the CLI (if you have the CLI tools installed)?
  3. What do you have set as your login shell in the macOS User settings? (You need to right click and "Advanced options..." to see these) screenshot-2024-03-04-10 37 35@2x
  4. What shell do you get in Terminal.app?
thapabishwa-plerionaut commented 8 months ago

What happens if you open it by clicking on Zed.app in /Applications?

Works as expected.

image

And what happens if you launch it via the CLI (if you have the CLI tools installed)?

Works as expected via CLI too.

image

What do you have set as your login shell in the macOS User settings? (You need to right click and "Advanced options..." to see these)

image

What shell do you get in Terminal.app?

Terminal.app image

iterm2.app image

mrnugget commented 8 months ago

Huh. So what happens when you start Alacritty.app? (That's what we use for the built-in terminal)

Do you have any plugins in Raycast that set a $SHELL or something?

aspeth commented 6 months ago

+1 to this issue - when opened via Raycast, Zed says my shell is /bin/sh despite having it set to /bin/zsh in my settings.json, but when opened via Finder or Spotlight it respects the setting. My login shell in the macOS User settings is /bin/zsh and I don't believe I have any Raycast plugins that set a $SHELL

Not a huge problem since things work as expected when opened with anything that's not Raycast, just wanted to add my experience here.

mrnugget commented 6 months ago

@aspeth can you try to reproduce what happens when you just launch Alacritty.app, from the Dock and from Raycast?

aspeth commented 6 months ago

echo $SHELL in Alacritty shows /bin/zsh when opened via Raycast as well as from the dock, but when opened via Raycast can't find commands in my .zshrc (brew, starship, and atuin, specifically) even after running source ~/.zshrc but has no problem finding those commands when opened via the dock.

mrnugget commented 6 months ago

This is so weird. I really wonder whether there isn't something going on inside Raycast wrt to env variables.

tkgalk commented 6 months ago

I'm having a similar issue. Zed is trying to open fish and fails because fish is no longer installed on the system. My shell is set to "system", my default shell is zsh. Nothing in the Zed's settings seems to be pointing to fish, but it keeps trying to use it.

mrnugget commented 6 months ago

I'm having a similar issue.

When you open it via Raycast?

tkgalk commented 6 months ago

When you open it via Raycast?

No. When running Zed in general. It is a different case, I don't even have Raycast, but Zed trying to pick a weird shell is similar. I thought I'd mention it just on the off chance it helps with debugging.

mrnugget commented 6 months ago

@tkgalk can you also try running Alacritty.app? I'm wondering if you have the same problem there. That would help a lot with the debugging.

tkgalk commented 6 months ago

No, Alacritty seems to respect the default shell.

mrnugget commented 6 months ago

Found something here: https://github.com/neovide/neovide/issues/2394

Looks like Raycast doesn't forward the $SHELL variable.

mrnugget commented 6 months ago

I dug into this a bit, here's what I found:

  1. Raycast doesn't seem to forward SHELL environment variable to programs. But ... I can't reproduce that.
  2. Alacritty falls back to reading the shell from the passwd file when no SHELL is set. https://github.com/alacritty/alacritty/blob/79b686df419d90e5557d1b7000f51f012986c141/alacritty_terminal/src/tty/unix.rs#L136-L171
  3. When no Zed settings specify the terminal.shell, then we use the Alacritty default.

So, to debug, here's a few things I need.

I wrote a little program to reproduce what alacritty does:

// main.c
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

struct Passwd {
  const char *name;
  const char *dir;
  const char *shell;
};

struct Passwd get_pw_entry(char *buf, size_t buflen) {
  struct passwd *entry;
  struct Passwd result;

  memset(&result, 0, sizeof(struct Passwd)); // Zero out the result struct

  uid_t uid = getuid();
  int status;

  struct passwd pw;
  status = getpwuid_r(uid, &pw, buf, buflen, &entry);

  if (status != 0) {
    perror("getpwuid_r failed");
    exit(EXIT_FAILURE);
  }

  if (entry == NULL) {
    fprintf(stderr, "pw not found\n");
    exit(EXIT_FAILURE);
  }

  // Sanity check.
  if (pw.pw_uid != uid) {
    fprintf(stderr, "UID mismatch\n");
    exit(EXIT_FAILURE);
  }

  // Fill the result struct
  result.name = pw.pw_name;
  result.dir = pw.pw_dir;
  result.shell = pw.pw_shell;

  return result;
}

int main() {
  const size_t buf_size = 1024;
  void *buf = malloc(buf_size);
  if (buf == NULL) {
    fprintf(stderr, "failed to malloc\n");
    exit(1);
  }

  struct Passwd result = get_pw_entry(buf, buf_size);

  printf("name: %s\n", result.name);
  printf("dir: %s\n", result.dir);
  printf("shell: %s\n", result.shell);

  return 0;
}

You can run it like this: cc -o main ./main.c && ./main That'll print the values that Alacritty uses, if no Shell is specified.

So, for everybody who experiences weird terminal behavior, I need the the following:

  1. If you have it configured: terminal: { shell: ... } from your Zed settings.json
  2. Start Zed via Raycast, run zed: open logs, find the last line that contains: set environment variables from shell. That should have the shell in it. Example: 2024-05-13T14:46:47+02:00 [INFO] set environment variables from shell:/bin/zsh, path:<myPATH> What is the shell?
  3. Start Zed via NOT Raycast, run zed: open logs, find the last line that contains: set environment variables from shell. That should have the shell in it. What is the shell?
  4. Open Terminal.app (NOT via Raycast), do echo $SHELL, then run my program: cc -o main ./main.c && ./main - give me the output
  5. Open Terminal.app (NOT via Raycast), do unset $SHELL (!!), then run my program: cc -o main ./main.c && ./main - give me the output
  6. What's your $SHELL in your normal terminal emulator? Do you have that configured in the terminal emulator? Or not?
tkgalk commented 6 months ago

https://github.com/zed-industries/zed/discussions/11751 moved my issue here, as it doesn't seem to be connected to Raycast. My zed Terminal can't even open the shell, so I can't test that.

tkgalk commented 6 months ago

After fixing my issue with Zed, I installed Raycast just to help, but I can't reproduce the OP's problem. Zed seems to be correctly running the shell from Raycast.

  1. Configured to shell: system.
  2. /bin/zsh.
  3. /bin/zsh.
  4. /bin/zsh.
  5. (It's unset SHELL, I think, not $SHELL). name: tkg dir: /Users/tkg shell: /bin/zsh
  6. /bin/zsh.

So at least for me seems like Zed is behaving correctly through both Raycast and outside of it.

mrnugget commented 6 months ago

Another finding that might be related: Alacritty.app doesn't seem to pickup changes made with chsh to the default shell.

https://github.com/zed-industries/zed/assets/1185253/46fb7220-515b-419c-91cb-31a045d7910e

mrnugget commented 6 months ago

Figured out a little bit more my digging into Alacritty and compiling from source:

  1. When you chsh -s /new/-shell
  2. Start Alacritty from Finder

That new shell is not picked up, because Finder does set the $SHELL env variable, but it only gets updated once Finder is restarted.

There's so much environment variables and state involved here, especially when using Raycast/Finder (which are long-running applications) that I think the safest step for further reproduction of bugs is: Make sure you've restarted your computer after making changes to the default shell.