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

emmet-language-server fails to launch on windows #21834

Open
1 task done
notpeter opened this issue Dec 11, 2024 · 5 comments
Open
1 task done

emmet-language-server fails to launch on windows #21834

notpeter opened this issue Dec 11, 2024 · 5 comments
Labels
bug [core label] emmet Emmet tooling support windows

Comments

@notpeter
Copy link
Member

notpeter commented Dec 11, 2024

Check for existing issues

  • Completed

Describe the bug / provide steps to reproduce it

emmet-language-server fails to launch on windows

Originally reported by @fbtwitter here:

Environment

Unknown. Windows.
Probably v0.165 or v0.166

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

No response

If applicable, attach your Zed.log file to this issue.

Language server error: emmet-language-server

oneshot canceled
-- stderr--
C:\Users\User\AppData\Local\Zed\extensions\work\emmet\node_modules\.bin\emmet-language-server:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
          ^^^^^^^

SyntaxError: missing ) after argument list
    at wrapSafe (node:internal/modules/cjs/loader:1515:18)
    at Module._compile (node:internal/modules/cjs/loader:1537:20)
    at Object..js (node:internal/modules/cjs/loader:1708:10)
    at Module.load (node:internal/modules/cjs/loader:1318:32)
    at Function._load (node:internal/modules/cjs/loader:1128:12)
    at TracingChannel.traceSync (node:diagnostics_channel:322:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:219:24)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:170:5)
    at node:internal/main/run_main_module:36:49
@notpeter notpeter added bug [core label] triage Maintainer needs to classify the issue admin read Pending admin review windows emmet Emmet tooling support and removed triage Maintainer needs to classify the issue admin read Pending admin review labels Dec 11, 2024
@notpeter
Copy link
Member Author

I'm not positive where exactly this line of code is coming from:

basedir=$(dirname "$(echo "$0" | sed -e 's,\,/,g')")

I did some digging and found a bunch of references to Node incorrectly creating bash scripts under .bin, but only on windows. For example on macOS my .bin/emmet-language-server is a node script:

#!/usr/bin/env node
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const emmet_1 = require("emmet");
...

The root cause is likely a windows/node thing (no idea how to fix).
The proximate cause is zed trigger spawn the bin script via the equivalent of:

node node_modules/.bin/emmet-language-server

instead of directly calling:

node_modules/.bin/emmet-language-server

const SERVER_PATH: &str = "node_modules/.bin/emmet-language-server";

let server_path = self.server_script_path(language_server_id)?;
Ok(zed::Command {
command: zed::node_binary_path()?,
args: vec![
env::current_dir()
.unwrap()
.join(&server_path)
.to_string_lossy()
.to_string(),
"--stdio".to_string(),
],
env: Default::default(),
})

Not sure whether there's something Zed should do when invoking npm when installing emmet-language-server to fix the created .bin or whether the emmet.rs code should be changed to directly invoke node_modules/.bin/emmet-language-server (do we need to adjust env pathing to make sure it uses the right node?) or to invoke node node_modules/emmet-language-server/out/server.js.

But thanks for reporting.

@fbtwitter
Copy link

fbtwitter commented Dec 15, 2024

Hello @notpeter,

Thank you for addressing and looking into the issue I encountered earlier.

I’ve been rebuilding the version daily, and now it seems like the error has progressed to something like this:


oneshot canceled
-- stderr--
node:internal/modules/cjs/loader:1147
  throw err;
  ^

Error: Cannot find module 'C:\C:\Users\User\AppData\Local\Zed\extensions\work\emmet\node_modules\.bin\emmet-language-server'
    at Module._resolveFilename (node:internal/modules/cjs/loader:1144:15)
    at Module._load (node:internal/modules/cjs/loader:985:27)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)
    at node:internal/main/run_main_module:28:49 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

Node.js v20.11.1

It appears the module cannot be located, as the path is also incorrect: 'E:\C:'.

I hope this provides some insights into fixing the issue and identifying the root cause.

Thank you

@Rahullkumr
Copy link

Language server error: vscode-html-language-server

oneshot canceled
-- stderr--
node:internal/modules/cjs/loader:1252
throw err;
^

Error: Cannot find module 'C:\C:\Users\rahul\AppData\Local\Zed\extensions\work\html\node_modules@zed-industries\vscode-langservers-extracted\bin\vscode-html-language-server'
at Function._resolveFilename (node:internal/modules/cjs/loader:1249:15)
at Function._load (node:internal/modules/cjs/loader:1075:27)
at TracingChannel.traceSync (node:diagnostics_channel:322:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:219:24)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:170:5)
at node:internal/main/run_main_module:36:49 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}

Node.js v22.12.0

@fbtwitter
Copy link

I believe this issue is not limited to Emmet, vscode-html, or any specific extensions; it seems to occur consistently, even with the Vue Language Server. It might be related to the setup or configuration of the installation method, which could be causing Zed Editor to behave unexpectedly. Could you please look into this issue? Since LSP is essential for enabling IntelliSense and other code functionalities, resolving this would greatly improve the experience.

@asuras-coding
Copy link

asuras-coding commented Dec 28, 2024

I encountered the same with various other language servers. This seems to affect all lsp's that are installed with node under the hood.
I also have no experience with rust so i don't know how to find out where exactly the node-code is called from zed-side. It would be interesting to see what exactly leaves zed in order run or interact with the lsp.

It looks like creating the path prefixes a path with the current project directory's drive. I tried out different project locations and ended up with different prefixes. I also tried to ensure all programs like zed, node and the project itself are on c drive, but that didnt change anything. Also I tried to search through the zed code for something like "C:" or target_os = "windows" to find some places where some special windows logic is applied. It looks like there is some root-drive prefix added somewhere where it shouldnt.

For my case i tried to use the docker-extension which comes with two community-git solutions for dockerfiles and docker compose. while installation worked, starting the lsp actually failed due to the issue above. However I created my own settings.json for the Dockerfile and got it working:

{
  "languages": {
    "Dockerfile": {
      "language_servers": ["dockerfile-language-server"]
    }
  },
  "lsp": {
    "dockerfile-language-server": {
      "binary": {
        "path": "C:\\Program Files\\nodejs\\node.exe",
        "arguments": [
          "C:\\Users\\asuras\\AppData\\Local\\Zed\\extensions\\work\\dockerfile\\node_modules\\dockerfile-language-server-nodejs\\bin\\docker-langserver",
          "--stdio"
        ]
      }
    }
  }
}

When i now prefix the first argument with D:\ I get my initial error again. Therefore the composition of the path for various extensions and language servers seems to incorrectly create the argument-path to the language server.

The first argument (lsp-path) in the dockerfile-extension gets composed like so:

// https://github.com/d1y/dockerfile.zed/blob/master/src/lib.rs
const SERVER_PATH: &str = "node_modules/dockerfile-language-server-nodejs/bin/docker-langserver"; // that is &server_path
fn server_exists(&self) -> bool {
        fs::metadata(SERVER_PATH).map_or(false, |stat| stat.is_file())
    }

env::current_dir()
     .unwrap()
    .join(&server_path)
    .to_string_lossy()
    .to_string(),

Therefore env::current_dir() which seems to be a rust std-lib function seems to return an incorrect value? Also either server_exists does work or on each launch the extension tries to install the language-server again. If server_exists works, maybe using fs::canonicalize(server_path) instead of env::durrent_dir() could fix this for good.

Also not sure if these language-server issues are related to core zed, or there is just a common issue that gets baked into all the extensions for languages by accident.

Also² I took a look into the official zed html-extension which is uses the vscode-html-language-server. Its basically the same code as the docker-lsp extensions uses, therefore i guess that most of the lsp issues regarding node can be fixed by fixing this prefix-issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug [core label] emmet Emmet tooling support windows
Projects
None yet
Development

No branches or pull requests

4 participants