tailwindlabs / tailwindcss-intellisense

Intelligent Tailwind CSS tooling for Visual Studio Code
2.74k stars 183 forks source link

Don't use `InitializeParams.rootUri` if `workspaceFolders` is specified #950

Closed alexander-doroshko closed 2 months ago

alexander-doroshko commented 2 months ago

Hi from JetBrains,

The LSP spec deprecates InitializeParams.rootUri in favour of workspaceFolders.

I noticed that rootUri is used unconditionally in the tw.ts file.

This causes the following problem. The IDE sends the initialize request as follows:

{
  "method": "initialize",
  "params": {
    ...
    "rootUri": null,
    "workspaceFolders": [
      {
        "uri": "file:///foo/bar",
        "name": "bar"
      },
      {
        "uri": "file:///foo/baz",
        "name": "baz"
      }
    ]
  }
}

and the server fails to initialize, it says No workspace folders found, not initializing.

In my understanding, if workspaceFolders is given, the server should ignore rootUri.

thecrypticace commented 2 months ago

This one was already on my radar but thanks for the reminder! We don't look at workspaceFolders at all right now and we definitely should. I noticed the deprecations after updating the LSP-related packages. There's some things I need to think through I think about how things need to work when using them but I'm planning to do so this week if I can — otherwise next week.

alexander-doroshko commented 2 months ago

Thanks. I've worked it around in the JetBrains Tailwind CSS plugin by starting a separate LSP server for each root. But I'll be happy to remove this workaround on our end once the LSP server supports workspaceFolders.

thecrypticace commented 2 months ago

@alexander-doroshko Sounds good!

Feel free to ping me if you run into other stuff or have questions/ideas/suggestions đź‘Ť

thecrypticace commented 2 months ago

Can you test the latest insiders build of @tailwindcss/language-server to see if things work as you expect?

npm install @tailwindcss/language-server@insiders
alexander-doroshko commented 2 months ago

Cool, 0.0.0-insiders.830dc0a works for me. I tried a simple scenario with a project with two roots. I haven't checked how it handles multiple package.json files, multiple node_modules folders, different tailwindcss package versions in different workspace roots, or multiple config files. I trust it works perfectly as usual :)

alexander-doroshko commented 2 months ago

Update: it seems that @tailwindcss/language-server version 0.0.0-insiders.830dc0a works if the tailwindcss package version is 3.4.3, but doesn't work with 0.0.0-insiders.f1f419a or 4.0.0-alpha.14. I don't get classes completion. Is it expected?

@tailwindcss/language-server version 0.0.16 seems to work fine with the tailwindcss package 0.0.0-insiders.f1f419a and 4.0.0-alpha.14.

thecrypticace commented 2 months ago

Hmm it definitely should. I'll take a look.

Any chance you could provide the logs and/or messages are you getting from the server in that case?

alexander-doroshko commented 2 months ago

Sure. It's a trivial project with 3 files: package.json, tailwind.config.js, and index.html.

{ "devDependencies": { "tailwindcss": "4.0.0-alpha.14" } }
module.exports = { }
<div class=""></div>

Tailwind CSS server doesn't throw any errors, but looks like it doesn't detect a project ([Global] Creating projects: []). So it simply returs null as a completion response (the last line):

 --> {"jsonrpc":"2.0","id":"1","method":"initialize","params":{"processId":null,"rootPath":"/Users/alexander.doroshko/WebstormProjects/tailwind_insiders","rootUri":"file:///Users/alexander.doroshko/WebstormProjects/tailwind_insiders","initializationOptions":{"userLanguages":{"ftl":"html","jinja":"html","jinja2":"html","smarty":"html","tmpl":"gohtml","cshtml":"html","vbhtml":"html","razor":"html"}},"capabilities":{"workspace":{"workspaceEdit":{"documentChanges":true,"resourceOperations":["create"],"failureHandling":"abort"},"didChangeWatchedFiles":{"relativePatternSupport":true,"dynamicRegistration":true},"executeCommand":{"dynamicRegistration":false},"workspaceFolders":true},"textDocument":{"completion":{"completionItem":{"snippetSupport":true,"documentationFormat":["markdown","plaintext"],"deprecatedSupport":true,"tagSupport":{"valueSet":[1]},"insertReplaceSupport":true,"resolveSupport":{"properties":["documentation"]},"labelDetailsSupport":true},"completionList":{"itemDefaults":["commitCharacters","editRange","insertTextFormat","insertTextMode","data"]}},"hover":{"contentFormat":["markdown","plaintext"]},"formatting":{"dynamicRegistration":true},"definition":{"linkSupport":true},"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["quickfix","","source","refactor"]}},"disabledSupport":true},"publishDiagnostics":{"tagSupport":{"valueSet":[1,2]},"versionSupport":true}},"window":{"showMessage":{},"showDocument":{"support":true}},"general":{"staleRequestSupport":{"cancel":true,"retryOnContentModified":[]}}},"clientInfo":{"name":"WebStorm","version":"242.SNAPSHOT"},"workspaceFolders":[{"uri":"file:///Users/alexander.doroshko/WebstormProjects/tailwind_insiders","name":"tailwind_insiders"}]}}
 <-- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"Setting up server…"}}
 <-- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"Listening for messages…"}}
 <-- {"jsonrpc":"2.0","id":"1","result":{"capabilities":{"textDocumentSync":1,"hoverProvider":true,"colorProvider":true,"codeActionProvider":true,"documentLinkProvider":{},"completionProvider":{"resolveProvider":true,"triggerCharacters":["\"","'","`"," ",".","(","[","]","!","/","-",":"]}}}}
 --> {"jsonrpc":"2.0","method":"initialized","params":{}}
 --> {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///Users/alexander.doroshko/WebstormProjects/tailwind_insiders/src/index.html","languageId":"html","version":0,"text":"\u003cdiv class\u003d\"\"\u003e\u003c/div\u003e"}}}
 <-- {"jsonrpc":"2.0","id":0,"method":"workspace/configuration","params":{"items":[{"section":"editor"}]}}
 --> {"jsonrpc":"2.0","id":0,"result":[{"tabSize":4}]}
 <-- {"jsonrpc":"2.0","id":1,"method":"workspace/configuration","params":{"items":[{"section":"tailwindCSS"}]}}
 <-- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"Searching for Tailwind CSS projects in the workspace's folders."}}
 <-- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"{\"tailwind\":{\"version\":\"4.0.0-alpha.14\",\"features\":[\"css-at-theme\",\"layer:base\",\"content-list\"],\"isDefaultVersion\":false}}"}}
 <-- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"[Global] Creating projects: []"}}
 <-- {"jsonrpc":"2.0","id":2,"method":"client/registerCapability","params":{"registrations":[{"id":"c49b12e3-cd72-46f4-bdb2-6365fad3478e","method":"workspace/didChangeWatchedFiles","registerOptions":{"watchers":[{"globPattern":"**/{tailwind,tailwind.config,tailwind.*.config,tailwind.config.*}.{js,cjs,ts,mjs}"},{"globPattern":"**/{package-lock.json,yarn.lock,pnpm-lock.yaml}"},{"globPattern":"**/*.{css,scss,sass,less,pcss}"}]}}]}}
 --> {"jsonrpc":"2.0","id":2,"result":null}
 <-- {"jsonrpc":"2.0","id":3,"method":"client/registerCapability","params":{"registrations":[{"id":"ebc8c65a-6d71-4b1f-9959-130ec7aa7602","method":"workspace/didChangeWorkspaceFolders","registerOptions":{}}]}}
 --> {"jsonrpc":"2.0","id":3,"result":null}
 --> {"jsonrpc":"2.0","id":1,"result":[{"includeLanguages":{"ftl":"html","jinja":"html","jinja2":"html","smarty":"html","tmpl":"gohtml","cshtml":"html","vbhtml":"html","razor":"html"},"files":{"exclude":["**/.git/**","**/node_modules/**","**/.hg/**","**/.svn/**"]},"emmetCompletions":false,"classAttributes":["class","className","ngClass"],"colorDecorators":false,"showPixelEquivalents":true,"rootFontSize":16,"hovers":true,"suggestions":true,"codeActions":true,"validate":true,"lint":{"invalidScreen":"error","invalidVariant":"error","invalidTailwindDirective":"error","invalidApply":"error","invalidConfigPath":"error","cssConflict":"warning","recommendedVariantOrder":"warning"},"experimental":{"classRegex":[]}}]}
 --> {"jsonrpc":"2.0","id":"2","method":"textDocument/completion","params":{"context":{"triggerKind":1},"textDocument":{"uri":"file:///Users/alexander.doroshko/WebstormProjects/tailwind_insiders/src/index.html"},"position":{"line":0,"character":12}}}
 <-- {"jsonrpc":"2.0","id":"2","result":null}
thecrypticace commented 2 months ago

Weird — that's helpful! I'll see if I can figure out what's wrong today.

thecrypticace commented 2 months ago

Oh wait it could be the presence of the tailwind config file. That's not supported with v4 right now. Might be able to surface that better from the language server with an error message / warning / something else.

thecrypticace commented 2 months ago

Oh no it's actually that you don't have any css files that import tailwind in some manner. With v4 you need a CSS file in your project that contains @import "tailwindcss". We analyze all the CSS files in the project to look for multiple configs and follow the import graph for theme declarations.

alexander-doroshko commented 2 months ago

Makes sense, thanks. Just adding the CSS file while the LSP server was already running didn't help, but after restarting the LSP server it worked for me! So, works as designed.

alexander-doroshko commented 2 months ago

I've caught this once. I think I was moving an HTML file from one folder to another when it happened. Thought I couldn't reproduce it again.

Tailwind CSS: Unhandled rejection TypeError: Cannot read properties of null (reading 'match')
at Klt (.../tailwindcss-language-server:2920:15716)
at async d (.../tailwindcss-language-server:2920:18890)
at async .../tailwindcss-language-server:2920:19607
thecrypticace commented 2 months ago

Yeah, right now if the LSP is already running and you add the CSS file it won't get picked up. Definitely some improvements to be made there.

I've caught this once. I think I was moving an HTML file from one folder to another when it happened. Thought I couldn't reproduce it again.

A read of the code suggests that it was the CSS file that moved. Fix is here #956 :)

This bug is a good showcase for why I'm working to (slowly) migrate this codebase to strict types.

alexander-doroshko commented 2 months ago

A read of the code suggests that it was the CSS file that moved

I think I didn't have any CSS files in the project at that moment. Only those 3: package.json, tailwind.config.js, and index.html. And node_modules folder. IAFAIR, I moved HTML file from the project root folder to src.

I guess #956 fixes that NPE anyway.