diff --git a/eclipse-solargraph-plugin/src/main/java/io/github/pyvesb/eclipse_solargraph/utils/CommandHelper.java b/eclipse-solargraph-plugin/src/main/java/io/github/pyvesb/eclipse_solargraph/utils/CommandHelper.java index d3cada8..dbffddd 100644 --- a/eclipse-solargraph-plugin/src/main/java/io/github/pyvesb/eclipse_solargraph/utils/CommandHelper.java +++ b/eclipse-solargraph-plugin/src/main/java/io/github/pyvesb/eclipse_solargraph/utils/CommandHelper.java @@ -19,11 +19,16 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.core.runtime.Platform; public class CommandHelper { + private static final String MACOS_DSCL_SHELL_PREFIX = "UserShell: "; + + private static final AtomicReference DEFAULT_SHELL_MACOS = new AtomicReference<>(); + public static String findDirectory(String executable) { String executablePath = findPath(executable); if (!executablePath.isEmpty()) { @@ -62,13 +67,44 @@ public static String[] getAbsolutePlatformCommand(String command) { } public static String[] getPlatformCommand(String command) { - return isWindows() ? new String[] { "cmd.exe", "/c", command } : new String[] { "bash", "-c", "-l", command }; + if (isWindows()) { + return new String[] { "cmd.exe", "/c", command }; + } else if (isMacOS()) { + String defaultShellMacOS = DEFAULT_SHELL_MACOS.get(); + if (defaultShellMacOS == null) { + defaultShellMacOS = findDefaultShellMacOS(); + DEFAULT_SHELL_MACOS.set(defaultShellMacOS); + } + return new String[] { defaultShellMacOS, "-c", "-li", command }; + } + return new String[] { "bash", "-c", "-l", command }; } public static boolean isWindows() { return Platform.OS_WIN32.equals(Platform.getOS()); } + public static boolean isMacOS() { + return Platform.OS_MACOSX.equals(Platform.getOS()); + } + + // Inspired from https://github.com/eclipse-wildwebdeveloper/wildwebdeveloper/blob/0447608f659c1683da4816fff185d34ef54dcf8a/org.eclipse.wildwebdeveloper.embedder.node/src/org/eclipse/wildwebdeveloper/embedder/node/NodeJSManager.java#L297 + private static String findDefaultShellMacOS() { + String[] dsclCommand = new String[] { "/bin/bash", "-c", "-l", "dscl . -read ~/ UserShell" }; + try { + Process process = new ProcessBuilder(dsclCommand).redirectErrorStream(true).start(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String shell = reader.readLine(); + if (shell != null && shell.startsWith(MACOS_DSCL_SHELL_PREFIX)) { + return shell.substring(MACOS_DSCL_SHELL_PREFIX.length()); + } + } + } catch (IOException e) { + LogHelper.error("Failed to find location of default macOS shell, using '/bin/zsh' instead.", e); + } + return "/bin/zsh"; // Default shell since macOS 10.15. + } + private CommandHelper() { // Utility class. }