joaotavora/eglot

tailwindcss language server support

illia-danko opened this issue · 14 comments

Hello @joaotavora. It would be really nice to have TailwindCSS be a part of multi language support (I have failed to make an standalone client either). It would unleash frond-end developing as TailwindCSS framework becomes very popular nowadays.

The server could be installed as:
npm install -g @tailwindcss/language-server . See https://www.npmjs.com/package/@tailwindcss/language-server

Theoretically it should simply work by setting it as:

(add-to-list 'eglot-server-programs
			 '((web-mode :language-id "html") . ("tailwindcss-language-server" "--stdio")))

But unfortunately it doesn't:

[internal] Fri May 24 20:34:51 2024:
(:message "Running language server: tailwindcss-language-server --stdio")
[client-request] (id:1) Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :id 1 :method "initialize" :params
		  (:processId 274748 :rootPath "/home/idanko/github.com/illia-danko/slivce/" :rootUri "file:///home/idanko/github.com/illia-danko/slivce" :initializationOptions #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data
																																													   ())
					  :capabilities
					  (:workspace
					   (:applyEdit t :executeCommand
								   (:dynamicRegistration :json-false)
								   :workspaceEdit
								   (:documentChanges t)
								   :didChangeWatchedFiles
								   (:dynamicRegistration t)
								   :symbol
								   (:dynamicRegistration :json-false)
								   :configuration t :workspaceFolders t)
					   :textDocument
					   (:synchronization
						(:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t)
						:completion
						(:dynamicRegistration :json-false :completionItem
											  (:snippetSupport t :deprecatedSupport t :resolveSupport
															   (:properties
																["documentation" "details" "additionalTextEdits"])
															   :tagSupport
															   (:valueSet
																[1]))
											  :contextSupport t)
						:hover
						(:dynamicRegistration :json-false :contentFormat
											  ["markdown" "plaintext"])
						:signatureHelp
						(:dynamicRegistration :json-false :signatureInformation
											  (:parameterInformation
											   (:labelOffsetSupport t)
											   :activeParameterSupport t))
						:references
						(:dynamicRegistration :json-false)
						:definition
						(:dynamicRegistration :json-false :linkSupport t)
						:declaration
						(:dynamicRegistration :json-false :linkSupport t)
						:implementation
						(:dynamicRegistration :json-false :linkSupport t)
						:typeDefinition
						(:dynamicRegistration :json-false :linkSupport t)
						:documentSymbol
						(:dynamicRegistration :json-false :hierarchicalDocumentSymbolSupport t :symbolKind
											  (:valueSet
											   [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26]))
						:documentHighlight
						(:dynamicRegistration :json-false)
						:codeAction
						(:dynamicRegistration :json-false :codeActionLiteralSupport
											  (:codeActionKind
											   (:valueSet
												["quickfix" "refactor" "refactor.extract" "refactor.inline" "refactor.rewrite" "source" "source.organizeImports"]))
											  :isPreferredSupport t)
						:formatting
						(:dynamicRegistration :json-false)
						:rangeFormatting
						(:dynamicRegistration :json-false)
						:rename
						(:dynamicRegistration :json-false)
						:inlayHint
						(:dynamicRegistration :json-false)
						:publishDiagnostics
						(:relatedInformation :json-false :codeDescriptionSupport :json-false :tagSupport
											 (:valueSet
											  [1 2])))
					   :window
					   (:workDoneProgress t)
					   :general
					   (:positionEncodings
						["utf-32" "utf-8" "utf-16"])
					   :experimental #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data
												   ()))
					  :workspaceFolders
					  [(:uri "file:///home/idanko/github.com/illia-danko/slivce" :name "~/github.com/illia-danko/slivce/")]))
[server-reply] (id:1) Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :id 1 :result
		  (:capabilities
		   (:textDocumentSync 1 :hoverProvider t :colorProvider t :codeActionProvider t :documentLinkProvider nil :completionProvider
							  (:resolveProvider t :triggerCharacters
												["\"" "'" "`" " " "." "(" "[" "!" "/" ":"]))))
[client-notification] Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :method "initialized" :params #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data
															()))
[client-notification] Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :method "textDocument/didOpen" :params
		  (:textDocument
		   (:uri "file:///home/idanko/github.com/illia-danko/slivce/lib/slivce_web/components/layouts/root.html.heex" :version 0 :languageId "html" :text "<html>\n  <body class=\"\"></body>\n</html>\n")))
[client-notification] Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :method "workspace/didChangeConfiguration" :params
		  (:settings #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data
								   ())))
[server-request] (id:0) Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :id 0 :method "workspace/configuration" :params
		  (:items
		   [(:section "editor")]))
[client-reply] (id:0) Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :id 0 :result
		  [nil])
[server-request] (id:1) Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :id 1 :method "workspace/configuration" :params
		  (:items
		   [(:section "tailwindCSS")]))
[client-reply] (id:1) Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :id 1 :result
		  [nil])
[server-notification] Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :method "window/logMessage" :params
		  (:type 4 :message "[Global] Creating projects: [{\"folder\":\"/home/idanko/github.com/illia-danko/slivce\",\"configPath\":\"/home/idanko/github.com/illia-danko/slivce/assets/tailwind.config.js\",\"isUserConfigured\":false,\"documentSelector\":[{\"pattern\":\"/home/idanko/github.com/illia-danko/slivce/assets/tailwind.config.js\",\"priority\":0},{\"pattern\":\"/home/idanko/github.com/illia-danko/slivce/assets/**\",\"priority\":3},{\"pattern\":\"/home/idanko/github.com/illia-danko/slivce/**\",\"priority\":4}]}]"))
[server-request] (id:2) Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :id 2 :method "client/registerCapability" :params
		  (:registrations
		   [(:id "a2530c16-0eab-4c8c-99f6-6ba76818356b" :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}")]))]))
[client-reply] (id:2) ERROR Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :id 2 :error
		  (:code -32603 :message "Internal error"))
[server-notification] Fri May 24 20:34:51 2024:
(:jsonrpc "2.0" :method "window/logMessage" :params
		  (:type 3 :message "Registering request handler for workspace/didChangeWatchedFiles failed."))
[server-notification] Fri May 24 20:34:52 2024:
(:jsonrpc "2.0" :method "window/logMessage" :params
		  (:type 1 :message "Unhandled exception: Internal error\nError: Internal error\n    at Ae (/nix/store/00gakawfrjkbbivcpw274qy7r9m2j02h-tailwindcss-language-server-0.0.14/lib/node_modules/tailwindcss-intellisense/bin/tailwindcss-language-server:139:236)\n    at X (/nix/store/00gakawfrjkbbivcpw274qy7r9m2j02h-tailwindcss-language-server-0.0.14/lib/node_modules/tailwindcss-intellisense/bin/tailwindcss-language-server:138:6870)\n    at Immediate.<anonymous> (/nix/store/00gakawfrjkbbivcpw274qy7r9m2j02h-tailwindcss-language-server-0.0.14/lib/node_modules/tailwindcss-intellisense/bin/tailwindcss-language-server:138:6719)\n    at process.processImmediate (node:internal/timers:476:21)"))
[client-request] (id:2) Fri May 24 20:34:52 2024:
(:jsonrpc "2.0" :id 2 :method "textDocument/hover" :params
		  (:textDocument
		   (:uri "file:///home/idanko/github.com/illia-danko/slivce/lib/slivce_web/components/layouts/root.html.heex")
		   :position
		   (:line 1 :character 15)))
[server-reply] (id:2) ERROR Fri May 24 20:34:52 2024:
(:jsonrpc "2.0" :id 2 :error
		  (:code -32603 :message "Internal error"))
[internal] (id:2) ERROR Fri May 24 20:34:52 2024:
(:message "error ignored, status set (Internal error)" :id 2 :error -32603)
[client-notification] Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :method "textDocument/didChange" :params
		  (:textDocument
		   (:uri "file:///home/idanko/github.com/illia-danko/slivce/lib/slivce_web/components/layouts/root.html.heex" :version 1)
		   :contentChanges
		   [(:text "<html>\n  <body class=\"b\"></body>\n</html>\n")]))
[client-request] (id:3) Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :id 3 :method "textDocument/completion" :params
		  (:textDocument
		   (:uri "file:///home/idanko/github.com/illia-danko/slivce/lib/slivce_web/components/layouts/root.html.heex")
		   :position
		   (:line 1 :character 16)
		   :context
		   (:triggerKind 1)))
[server-reply] (id:3) ERROR Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :id 3 :error
		  (:code -32603 :message "Internal error"))
[client-request] (id:4) Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :id 4 :method "textDocument/completion" :params
		  (:textDocument
		   (:uri "file:///home/idanko/github.com/illia-danko/slivce/lib/slivce_web/components/layouts/root.html.heex")
		   :position
		   (:line 1 :character 16)
		   :context
		   (:triggerKind 1)))
[server-reply] (id:4) ERROR Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :id 4 :error
		  (:code -32603 :message "Internal error"))
[client-notification] Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :method "textDocument/didChange" :params
		  (:textDocument
		   (:uri "file:///home/idanko/github.com/illia-danko/slivce/lib/slivce_web/components/layouts/root.html.heex" :version 2)
		   :contentChanges
		   [(:text "<html>\n  <body class=\"bg\"></body>\n</html>\n")]))
[client-request] (id:5) Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :id 5 :method "textDocument/completion" :params
		  (:textDocument
		   (:uri "file:///home/idanko/github.com/illia-danko/slivce/lib/slivce_web/components/layouts/root.html.heex")
		   :position
		   (:line 1 :character 17)
		   :context
		   (:triggerKind 1)))
[server-reply] (id:5) ERROR Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :id 5 :error
		  (:code -32603 :message "Internal error"))
[client-request] (id:6) Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :id 6 :method "textDocument/completion" :params
		  (:textDocument
		   (:uri "file:///home/idanko/github.com/illia-danko/slivce/lib/slivce_web/components/layouts/root.html.heex")
		   :position
		   (:line 1 :character 17)
		   :context
		   (:triggerKind 1)))
[server-reply] (id:6) ERROR Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :id 6 :error
		  (:code -32603 :message "Internal error"))
[client-request] (id:7) Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :id 7 :method "textDocument/hover" :params
		  (:textDocument
		   (:uri "file:///home/idanko/github.com/illia-danko/slivce/lib/slivce_web/components/layouts/root.html.heex")
		   :position
		   (:line 1 :character 17)))
[server-reply] (id:7) ERROR Fri May 24 20:34:55 2024:
(:jsonrpc "2.0" :id 7 :error
		  (:code -32603 :message "Internal error"))
[internal] (id:7) ERROR Fri May 24 20:34:55 2024:
(:message "error ignored, status set (Internal error)" :id 7 :error -32603)
[client-request] (id:8) Fri May 24 20:34:57 2024:
(:jsonrpc "2.0" :id 8 :method "textDocument/hover" :params
		  (:textDocument
		   (:uri "file:///home/idanko/github.com/illia-danko/slivce/lib/slivce_web/components/layouts/root.html.heex")
		   :position
		   (:line 1 :character 16)))
[server-reply] (id:8) ERROR Fri May 24 20:34:57 2024:
(:jsonrpc "2.0" :id 8 :error
		  (:code -32603 :message "Internal error"))
[internal] (id:8) ERROR Fri May 24 20:34:57 2024:
(:message "error ignored, status set (Internal error)" :id 8 :error -32603)
[client-request] (id:9) Fri May 24 20:35:08 2024:
(:jsonrpc "2.0" :id 9 :method "textDocument/hover" :params
		  (:textDocument
		   (:uri "file:///home/idanko/github.com/illia-danko/slivce/lib/slivce_web/components/layouts/root.html.heex")
		   :position
		   (:line 3 :character 0)))
[server-reply] (id:9) ERROR Fri May 24 20:35:08 2024:
(:jsonrpc "2.0" :id 9 :error
		  (:code -32603 :message "Internal error"))
[internal] (id:9) ERROR Fri May 24 20:35:08 2024:
(:message "error ignored, status set (Internal error)" :id 9 :error -32603)

The file I edited:
root.html.heex

<html>
  <body class="bg[cursor_is_here]"></body>
</html>

By using neovim the following setup works:

The settings:

  lspconfig.tailwindcss.setup({
    on_attach = on_attach,
    capabilities = capabilities,
    filetypes = { "html", "elixir", "eelixir", "heex" },
    init_options = {
      userLanguages = {
        elixir = "html-eex",
        eelixir = "html-eex",
        heex = "html-eex",
      },
    },
    settings = {
      tailwindCSS = {
        experimental = {
          classRegex = {
            'class[:]\\s*"([^"]*)"',
          },
        },
      },
    },
  })

Neovim lsp logs are attached.
lsp.log

@joaotavora can you help to add tailwind server to eglot?

Hi @joaotavora @illia-danko, I'm trying to implement language server multiplexer for working with tailwindcss and other modes at once and I also reach this error, to complement this, I set debug on error and god this error on eglot side of things:

Debugger entered--Lisp error: (error "Glob ’**/{tailwind,tailwind.config,tailwind.*.conf...")
  error("Glob '%s' invalid at %s" "**/{tailwind,tailwind.config,tailwind.*.config,tai..." 4)
  eglot--glob-parse("**/{tailwind,tailwind.config,tailwind.*.config,tai...")
  eglot--glob-compile("**/{tailwind,tailwind.config,tailwind.*.config,tai..." t t)
  #f(compiled-function (jsonrpc-lambda-elem23) #<bytecode 0x4031d1bc139546c>)((:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai..."))
  mapcar(#f(compiled-function (jsonrpc-lambda-elem23) #<bytecode 0x4031d1bc139546c>) [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")])
  #f(compiled-function (arg1 arg2 arg3 &rest rest) "Handle dynamic registration of workspace/didChangeWatchedFiles." #<bytecode 0x12c4f49e24ec7e5f>)(#<eglot-lsp-server eglot-lsp-server-8b2cc72> workspace/didChangeWatchedFiles "5066d774-94a0-45dd-8a20-bf7928cc907c" :watchers [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")])
  apply(#f(compiled-function (arg1 arg2 arg3 &rest rest) "Handle dynamic registration of workspace/didChangeWatchedFiles." #<bytecode 0x12c4f49e24ec7e5f>) #<eglot-lsp-server eglot-lsp-server-8b2cc72> workspace/didChangeWatchedFiles ("5066d774-94a0-45dd-8a20-bf7928cc907c" :watchers [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")]))
  eglot-register-capability(#<eglot-lsp-server eglot-lsp-server-8b2cc72> workspace/didChangeWatchedFiles "5066d774-94a0-45dd-8a20-bf7928cc907c" :watchers [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")])
  eglot--register-unregister(#<eglot-lsp-server eglot-lsp-server-8b2cc72> [(:id "5066d774-94a0-45dd-8a20-bf7928cc907c" :method "workspace/didChangeWatchedFiles" :registerOptions (:watchers [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")]))] register)
  #f(compiled-function (arg1 arg2 &rest rest) "Handle server request client/registerCapability." #<bytecode 0x98867e952e244bc>)(#<eglot-lsp-server eglot-lsp-server-8b2cc72> client/registerCapability :registrations [(:id "5066d774-94a0-45dd-8a20-bf7928cc907c" :method "workspace/didChangeWatchedFiles" :registerOptions (:watchers [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")]))])
  apply(#f(compiled-function (arg1 arg2 &rest rest) "Handle server request client/registerCapability." #<bytecode 0x98867e952e244bc>) #<eglot-lsp-server eglot-lsp-server-8b2cc72> client/registerCapability (:registrations [(:id "5066d774-94a0-45dd-8a20-bf7928cc907c" :method "workspace/didChangeWatchedFiles" :registerOptions (:watchers [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")]))]))
  eglot-handle-request(#<eglot-lsp-server eglot-lsp-server-8b2cc72> client/registerCapability :registrations [(:id "5066d774-94a0-45dd-8a20-bf7928cc907c" :method "workspace/didChangeWatchedFiles" :registerOptions (:watchers [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")]))])
  apply(eglot-handle-request #<eglot-lsp-server eglot-lsp-server-8b2cc72> client/registerCapability (:registrations [(:id "5066d774-94a0-45dd-8a20-bf7928cc907c" :method "workspace/didChangeWatchedFiles" :registerOptions (:watchers [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")]))]))
  #f(compiled-function (server method params) #<bytecode -0xa345aeaf4ed0761>)(#<eglot-lsp-server eglot-lsp-server-8b2cc72> client/registerCapability (:registrations [(:id "5066d774-94a0-45dd-8a20-bf7928cc907c" :method "workspace/didChangeWatchedFiles" :registerOptions (:watchers [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")]))]))
  jsonrpc-connection-receive(#<eglot-lsp-server eglot-lsp-server-8b2cc72> (:jsonrpc "2.0" :id 2 :method "client/registerCapability" :params (:registrations [(:id "5066d774-94a0-45dd-8a20-bf7928cc907c" :method "workspace/didChangeWatchedFiles" :registerOptions (:watchers [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")]))])))
  #f(compiled-function (conn msg) #<bytecode -0x1d53e2caaf5afc55>)(#<eglot-lsp-server eglot-lsp-server-8b2cc72> (:jsonrpc "2.0" :id 2 :method "client/registerCapability" :params (:registrations [(:id "5066d774-94a0-45dd-8a20-bf7928cc907c" :method "workspace/didChangeWatchedFiles" :registerOptions (:watchers [(:globPattern "**/{tailwind,tailwind.config,tailwind.*.config,tai...") (:globPattern "**/{package-lock.json,yarn.lock,pnpm-lock.yaml}") (:globPattern "**/*.{css,scss,sass,less,pcss}")]))])))
  apply(#f(compiled-function (conn msg) #<bytecode -0x1d53e2caaf5afc55>) (#<eglot-lsp-server eglot-lsp-server-8b2cc72> (:jsonrpc "2.0" :id 2 :method "client/registerCapability" :params (:registrations [(:id "5066d774-94a0-45dd-8a20-bf7928cc907c" :method "workspace/didChangeWatchedFiles" :registerOptions (:watchers [... ... ...]))]))))
  timer-event-handler([t 26260 49043 927459 nil #f(compiled-function (conn msg) #<bytecode -0x1d53e2caaf5afc55>) (#<eglot-lsp-server eglot-lsp-server-8b2cc72> (:jsonrpc "2.0" :id 2 :method "client/registerCapability" :params (:registrations [(:id "5066d774-94a0-45dd-8a20-bf7928cc907c" :method "workspace/didChangeWatchedFiles" :registerOptions (:watchers ...))]))) nil 709000 nil])

All I can say is that's not the same error. Maybe you googled "tailwind css eglot error" and it landed you here. But that doesn't mean it is right? @tino415 your backtrace is truncated so I cannot tell why the language server sent what Eglot thinks is a broken glob pattern. Start a new conversation in discussions and add the missing information. Do NOT piggy pack onto this one, please

As to the original issue, @illia-danko,the error has a server-side backtrace there pointing to a server-side exception. Maybe send that to the server developers? Locally I just did this:

  • Install nvm and Node v20.15.1
  • npm install -g @tailwindcss/language-server
  • M-x package-install RET web-mode
  • create a file root.html.heex in ~/tmp/eglot-issue-1403
  • emacs -Q -f package-initialize root.html.heex -f web-mode -f eglot

When Emacs starts up, it asks me for a language server invocation . I type tailwindcss-languageserver and I get a single warnings about the server trying to register an unsupported capability (a minor server bug, but nothing serious).

Other than that, no errors, but no completion or hover or anything. But that's a completely different issue.

I don't know what else to do here, this is an unreproducible from me. The original backtrace was probably very tied to a specific version of taildwindcss/language-server. If you still get that backtrace, reply here. Else just create a new issue and make sure it is reproducible (run the recipe yourself).

@joaotavora sorry for not expanding backtrace, I did not noticed when copy pasting

So the pattern that is crashing eglot-glob--parse is

"**/{tailwind,tailwind.config,tailwind.*.config,tailwind.config.*}.{js,cjs,ts,mjs}"

And there are the registration capability lines from eglot log:

[jsonrpc] e[11:28:56.665] <-- client/registerCapability[2] {"jsonrpc":"2.0","id":2,"method":"client/registerCapability","params":{"registrations":[{"id":"b746060a-c55b-4d7e-b9d0-6328de535274","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] e[11:28:56.665] --> client/registerCapability[2] {"jsonrpc":"2.0","id":2,"error":{"code":-32603,"message":"Internal error"}}

Minimal example is therefore to run in scratch buffer

(eglot-glob--parse "**/{tailwind,tailwind.config,tailwind.*.config,tailwind.config.*}.{js,cjs,ts,mjs}")

My knowledge is language server protocol are not so deep, but I assume that this can mess up internal state of that language server protocol resulting in not processing any following message. I see that server is responding with same message code as eglot after failing registering those watcher. Also since it is same error as what collegue is experiencing, I assume it is related issue, but if you insist, I can create separate issue.

I assume it is related issue,

It could be and it could not be. We don't know.

Create a separate issue if you can provide ALL the elements (but really ALL the elements).
Create a separate conversation if you can't.

I tried to check versions, and I see that nixos has outdates tailwind lsp version 0.0.16, actual is 0.0.21, I will tree with never one and open issue if that will not solve it. Thank you for your time.

It is also happening with tailwind lsp 0.0.21 but when I tried as you write, use eglot instead of setting up eglot-ensure, which now I see is wrong to use on first run, if there is not tailwindcss config in repository, language server will just response that there is missing configuration, if there is tailwind config, it will crash on every request, I might create some minimal repository but besides implementing that one capability there is probably nothing to be done on eglot side of things

Actually eglot on initialize is sending "didChangeWatchedFiles":{"dynamicRegistration":true} so it is supposed to support that capabilty?

By "that one capability" do you mean the ability to process globs with nested glob patterns? If so, I am working on that. It could take a while or not, we'll see. It may or may not fix it. I still am not fully sure how to setup a web project that this server should presumably work in: the original regipe is borderline ambiguous.

Actually eglot on initialize is sending "didChangeWatchedFiles":{"dynamicRegistration":true} so it is supposed to support that capabilty?

And it does. But that's not the registration that the server requested

And it does. But that's not the registration that the server requested

interesting, now I see it is trying to register two capabilties, workspace/didChangeWorkspaceFolders and workspace/didChangeWatchedFiles, to second one eglot will respond with (:jsonrpc "2.0" :id 2 :error (:code -32603 :message "Internal error")), I created this repository https://github.com/tino415/tlw where you could go:

  • npm install
  • make crash
  • switch to buffer index.html and you should end up in Backtrace

I still can't repeat in clean repository crashing on every request, I will try later and notify you If I manage to do it.

I've reproduced your crash (which only happens when you add the debug-on-error). BTW, for next time, this suffices:

emacs -Q -f toggle-debug-on-error -l crash.el src/index.html -f eglot

Where crash.el is just this:

❯ cat crash.el
(with-eval-after-load 'eglot
  (add-to-list
   'eglot-server-programs
   '(mhtml-mode "tailwindcss-language-server")))

i.e. the auto-setup of major-mode/server.

I've fixed this crash with the attached patch, which adds supports for nested glob patterns that tailwind uses (the first server to use them that I'm aware of). I will test the patch in the coming days and perhaps push it to the upstream.

But it doesn't make any meaningful difference. The backtrace happening or not is just a consequence of your desire to debug Eglot internals. When debug-on-error is false, the server receives an "Internal error" response from Eglot and behaves exactly as it does when it doesn't receive such a reply. IOW, in my testing, I get exactly the same behaviour as described earlier in my comment: #1403 (comment)

I recommend you create a new issue and reuse your error reproduction recipe.

Hello, thank you, actually I was curious and wrote yesterday https://github.com/tino415/tailwindfix which basically wraps tailwind and override that one single pattern and with this it started to work. I also tested your patch and now it is working. Thank you for your work.

I've pushed the Eglot fix to Emacs master. It will appear in the next Eglot release but can be tested earlier in GNU-devel ELPA (https://elpa.gnu.org/devel/).

t started to work. I

As I said, I also "got it to work", but I didn't get it do to anything useful like completions or hover information. Maybe you could start a "show and tell" discussion topic explaining what setup you used to make this do something meaninful.