Getting Heex and ~H working in nvim with AstroNvim

here is the creator of the GitHub - AstroNvim/astrocommunity: A community repository of common plugin specifications repo, maybe u can add ur work to it? we have a lot of packs
if you need help you can join us at Discord

1 Like

Quick update…

While I have not created a “pack” for astrocommunity re @luxus above (although I may still if I get some time) I did move my custom config into a more officially sanctioned user config repo which you can now find here:

NOTE: You still have to install emmet_ls and tailwindcss language servers with :LspInstall, as well as the elixir and heex tree-sitter packages with :TSInstall.

You no longer need to manually install elixir-ls because the fabulous Elixir Tools plugin (included in the above config) will automatically install the right version to coexist with the new language server from Elixir Tools called Next LS, which is working great for me so far.

Hit me up in the above repo on GitHub or in this thread if you have any issues. I very likely screwed at least one thing up…

2 Likes

@ohnoimdead thanks for the config. I’m trying to set a similar thing up in helix, but I can’t figure out how the classRegex that you provide is supposed to work?

class[:]\\s*"([^"]*)" doesn’t match on <div class="bg-green-200">, does it?

I actually snagged that from @groig above, but it works in nvim:

Maybe there’s something else going on with your helix config? I have no experience with helix so will be of little use in debugging, sadly. But if you post your config maybe we can recruit some community help :+1:.

1 Like

What would be great actually if you could show me the debug info of the tailwind css initialisation call. That should show the config nvim sends to the lsp. So that I can compare it
I’m not at my pc right now so can’t send my config but I’ll post it later.

That didn’t make any sense to me either, so I removed it from my setup and completion still worked as expected. Makes sense that the TW LSP would already know about regular class context in HTML :slight_smile: Maybe that’s something for the magical emmet syntax (not something I use, so also not something I included in my setup).

1 Like

To be honest, I have no idea why that’s in there. I thought maybe it was for emmet as well, however, testing with and without it doesn’t get completions for something like div.bg-slate-200. Maybe @groig knows? This is what happens when one copy/pastes. :smiley:

1 Like

That regex is for enabling tailwind completion when using class:, like this:

image

2 Likes

Ahh, of course :man_facepalming:

1 Like

So, what would really help me if someone could post the debug output of their tailwindcss-lsp. I’ve just done this for mine (mind you output is from helix, but you can see what is being sent and received)

2023-08-27T20:36:03.774 helix_lsp::client [INFO] Using custom LSP config: {"tailwindCSS":{"experimental":{"classRegex":["class[:]\\s*\"([^\"]*)\""],"configFile":"assets/tailwind.config.js"},"includeLanguages":{"eelixir":"html-eex","elixir":"html-eex","heex":"html-eex"}}}
2023-08-27T20:36:03.774 helix_lsp::transport [INFO] tailwindcss-lsp-elixir -> {"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"general":{"positionEncodings":["utf-8","utf-32","utf-16"]},"textDocument":{"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"dataSupport":true,"disabledSupport":true,"isPreferredSupport":true,"resolveSupport":{"properties":["edit","command"]}},"completion":{"completionItem":{"deprecatedSupport":true,"insertReplaceSupport":true,"resolveSupport":{"properties":["documentation","detail","additionalTextEdits"]},"snippetSupport":true,"tagSupport":{"valueSet":[1]}},"completionItemKind":{}},"hover":{"contentFormat":["markdown"]},"inlayHint":{"dynamicRegistration":false},"publishDiagnostics":{"versionSupport":true},"rename":{"dynamicRegistration":false,"honorsChangeAnnotations":false,"prepareSupport":true},"signatureHelp":{"signatureInformation":{"activeParameterSupport":true,"documentationFormat":["markdown"],"parameterInformation":{"labelOffsetSupport":true}}}},"window":{"workDoneProgress":true},"workspace":{"applyEdit":true,"configuration":true,"didChangeConfiguration":{"dynamicRegistration":false},"didChangeWatchedFiles":{"dynamicRegistration":true,"relativePatternSupport":false},"executeCommand":{"dynamicRegistration":false},"inlayHint":{"refreshSupport":false},"symbol":{"dynamicRegistration":false},"workspaceEdit":{"documentChanges":true,"failureHandling":"abort","normalizesLineEndings":false,"resourceOperations":["create","rename","delete"]},"workspaceFolders":true}},"clientInfo":{"name":"helix","version":"23.05"},"initializationOptions":{"tailwindCSS":{"experimental":{"classRegex":["class[:]\\s*\"([^\"]*)\""],"configFile":"assets/tailwind.config.js"},"includeLanguages":{"eelixir":"html-eex","elixir":"html-eex","heex":"html-eex"}}},"processId":20032,"rootPath":"/home/thomas/Workspace/temp/tailwind_test","rootUri":"file:///home/thomas/Workspace/temp/tailwind_test","workspaceFolders":[{"name":"tailwind_test","uri":"file:///home/thomas/Workspace/temp/tailwind_test"}]},"id":0}
2023-08-27T20:36:05.961 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","id":0,"result":{"capabilities":{"textDocumentSync":1,"hoverProvider":true,"colorProvider":true,"codeActionProvider":true,"documentLinkProvider":{},"completionProvider":{"resolveProvider":true,"triggerCharacters":["\"","'","`"," ",".","(","[","!","/",":"]}}}}
2023-08-27T20:36:05.962 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"capabilities":{"codeActionProvider":true,"colorProvider":true,"completionProvider":{"resolveProvider":true,"triggerCharacters":["\"","'","`"," ",".","(","[","!","/",":"]},"documentLinkProvider":{},"hoverProvider":true,"textDocumentSync":1}}
2023-08-27T20:36:05.962 helix_lsp::transport [INFO] tailwindcss-lsp-elixir -> {"jsonrpc":"2.0","method":"initialized","params":{}}
2023-08-27T20:36:05.962 helix_lsp::transport [INFO] tailwindcss-lsp-elixir -> {"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"tailwindCSS":{"experimental":{"classRegex":["class[:]\\s*\"([^\"]*)\""],"configFile":"assets/tailwind.config.js"},"includeLanguages":{"eelixir":"html-eex","elixir":"html-eex","heex":"html-eex"}}}}}
2023-08-27T20:36:05.962 helix_lsp::transport [INFO] tailwindcss-lsp-elixir -> {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"languageId":"elixir","text":"defmodule TailwindTestWeb.Layouts do\n  use TailwindTestWeb, :html\n\n  embed_templates \"layouts/*\"\n\n  def test do\n    ~H\"\"\"\n    <div class=\"bg-green-500\"></div>\n    \"\"\"\n  end\nend\n","uri":"file:///home/thomas/Workspace/temp/tailwind_test/lib/tailwind_test_web/components/layouts.ex","version":0}}}
2023-08-27T20:36:05.963 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","id":0,"method":"workspace/configuration","params":{"items":[{"section":"editor"}]}}
2023-08-27T20:36:05.963 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","id":1,"method":"workspace/configuration","params":{"items":[{"section":"tailwindCSS"}]}}
2023-08-27T20:36:05.963 helix_lsp::transport [INFO] tailwindcss-lsp-elixir -> {"jsonrpc":"2.0","result":[null],"id":0}
2023-08-27T20:36:05.963 helix_lsp::transport [INFO] tailwindcss-lsp-elixir -> {"jsonrpc":"2.0","result":[{"experimental":{"classRegex":["class[:]\\s*\"([^\"]*)\""],"configFile":"assets/tailwind.config.js"},"includeLanguages":{"eelixir":"html-eex","elixir":"html-eex","heex":"html-eex"}}],"id":1}
2023-08-27T20:36:05.964 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"[Global] Creating projects: [{\"folder\":\"/home/thomas/Workspace/temp/tailwind_test\",\"configPath\":\"/home/thomas/Workspace/temp/tailwind_test/assets/tailwind.config.js\",\"documentSelector\":[{\"priority\":0,\"pattern\":\"/home/thomas/Workspace/temp/tailwind_test/**\"}],\"isUserConfigured\":true}]"}}
2023-08-27T20:36:05.965 helix_term::application [INFO] window/logMessage: LogMessageParams { typ: Log, message: "[Global] Creating projects: [{\"folder\":\"/home/thomas/Workspace/temp/tailwind_test\",\"configPath\":\"/home/thomas/Workspace/temp/tailwind_test/assets/tailwind.config.js\",\"documentSelector\":[{\"priority\":0,\"pattern\":\"/home/thomas/Workspace/temp/tailwind_test/**\"}],\"isUserConfigured\":true}]" }
2023-08-27T20:36:05.965 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","id":2,"method":"client/registerCapability","params":{"registrations":[{"id":"0dd0d772-b218-49b9-a059-b8827a6cb6e6","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}"}]}}]}}
2023-08-27T20:36:05.965 helix_lsp::transport [INFO] tailwindcss-lsp-elixir -> {"jsonrpc":"2.0","result":null,"id":2}
2023-08-27T20:36:07.315 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"[Global] Adding watch patterns: /home/thomas/Workspace/temp/tailwind_test/assets/tailwind.config.js, /home/thomas/Workspace/temp/tailwind_test/assets, /home/thomas/Workspace/temp/tailwind_test"}}
2023-08-27T20:36:07.315 helix_term::application [INFO] window/logMessage: LogMessageParams { typ: Log, message: "[Global] Adding watch patterns: /home/thomas/Workspace/temp/tailwind_test/assets/tailwind.config.js, /home/thomas/Workspace/temp/tailwind_test/assets, /home/thomas/Workspace/temp/tailwind_test" }
2023-08-27T20:36:07.315 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","id":3,"method":"client/registerCapability","params":{"registrations":[{"id":"65e61a0c-aedc-4ff6-a090-e76b0ee9bbf2","method":"workspace/didChangeWatchedFiles","registerOptions":{"watchers":[{"globPattern":"/home/thomas/Workspace/temp/tailwind_test/assets/tailwind.config.js"},{"globPattern":"/home/thomas/Workspace/temp/tailwind_test/assets"},{"globPattern":"/home/thomas/Workspace/temp/tailwind_test"}]}}]}}
2023-08-27T20:36:07.315 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"[assets/tailwind.config.js] Initializing..."}}
2023-08-27T20:36:07.315 helix_term::application [INFO] window/logMessage: LogMessageParams { typ: Log, message: "[assets/tailwind.config.js] Initializing..." }
2023-08-27T20:36:07.315 helix_lsp::transport [INFO] tailwindcss-lsp-elixir -> {"jsonrpc":"2.0","result":null,"id":3}
2023-08-27T20:36:07.315 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"[assets/tailwind.config.js] Failed to load workspace modules."}}
2023-08-27T20:36:07.315 helix_term::application [INFO] window/logMessage: LogMessageParams { typ: Log, message: "[assets/tailwind.config.js] Failed to load workspace modules." }
2023-08-27T20:36:07.315 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"[assets/tailwind.config.js] Using bundled version of `tailwindcss`: v3.3.0"}}
2023-08-27T20:36:07.315 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"[assets/tailwind.config.js] Using bundled version of `postcss`: v8.3.9"}}
2023-08-27T20:36:07.315 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"[assets/tailwind.config.js] Building..."}}
2023-08-27T20:36:07.315 helix_term::application [INFO] window/logMessage: LogMessageParams { typ: Log, message: "[assets/tailwind.config.js] Using bundled version of `tailwindcss`: v3.3.0" }
2023-08-27T20:36:07.315 helix_term::application [INFO] window/logMessage: LogMessageParams { typ: Log, message: "[assets/tailwind.config.js] Using bundled version of `postcss`: v8.3.9" }
2023-08-27T20:36:07.316 helix_term::application [INFO] window/logMessage: LogMessageParams { typ: Log, message: "[assets/tailwind.config.js] Building..." }
2023-08-27T20:36:07.316 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","id":4,"method":"workspace/configuration","params":{"items":[{"section":"editor","scopeUri":"file:///home/thomas/Workspace/temp/tailwind_test/lib/tailwind_test_web/components/layouts.ex"}]}}
2023-08-27T20:36:07.316 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","id":5,"method":"workspace/configuration","params":{"items":[{"section":"tailwindCSS","scopeUri":"file:///home/thomas/Workspace/temp/tailwind_test/lib/tailwind_test_web/components/layouts.ex"}]}}
2023-08-27T20:36:07.316 helix_lsp::transport [INFO] tailwindcss-lsp-elixir -> {"jsonrpc":"2.0","result":[null],"id":4}
2023-08-27T20:36:07.316 helix_lsp::transport [INFO] tailwindcss-lsp-elixir -> {"jsonrpc":"2.0","result":[{"experimental":{"classRegex":["class[:]\\s*\"([^\"]*)\""],"configFile":"assets/tailwind.config.js"},"includeLanguages":{"eelixir":"html-eex","elixir":"html-eex","heex":"html-eex"}}],"id":5}
2023-08-27T20:36:07.318 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///home/thomas/Workspace/temp/tailwind_test/lib/tailwind_test_web/components/layouts.ex","diagnostics":[]}}

On thing that stands out a bit, now that I read through all of this, is:

**2023-08-27T20:41:00.613 helix_lsp::transport [INFO] tailwindcss-lsp-elixir <- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"[assets/tailwind.config.js] Failed to load workspace modules."}}

EDIT: that is probably not the problem as it loads the bundled tailwind after that.

I get that failure too, and mine works fine:

[INFO][2023-08-27 15:47:17] .../vim/lsp/rpc.lua:661	"Starting RPC client"	{  args = { "--stdio" },  cmd = "/Users/jk/.local/share/nvim/mason/bin/tailwindcss-language-server",  extra = {    cwd = "/Users/jk/work/p17"  }}
[INFO][2023-08-27 15:47:17] ...lsp/handlers.lua:489	'[Global] Creating projects: [{"folder":"/Users/jk/work/p17","configPath":"/Users/jk/work/p17/assets/tailwind.config.js","isUserConfigured":false,"documentSelector":[{"pattern":"/Users/jk/work/p17/assets/tailwind.config.js","priority":0},{"pattern":"/Users/jk/work/p17/assets/**","priority":3},{"pattern":"/Users/jk/work/p17/**","priority":4}]}]'
[INFO][2023-08-27 15:47:17] .../lua/vim/lsp.lua:1336	"LSP[tailwindcss]"	"server_capabilities"	{  server_capabilities = {    codeActionProvider = true,    colorProvider = true,    completionProvider = {      resolveProvider = true,      triggerCharacters = { '"', "'", "`", " ", ".", "(", "[", "!", "/", ":" }    },    documentLinkProvider = vim.empty_dict(),    hoverProvider = true,    textDocumentSync = {      change = 1,      openClose = true,      save = {        includeText = false      },      willSave = false,      willSaveWaitUntil = false    }  }}
[INFO][2023-08-27 15:47:17] ...lsp/handlers.lua:489	"[assets/tailwind.config.js] Initializing..."
[INFO][2023-08-27 15:47:17] ...lsp/handlers.lua:489	"[assets/tailwind.config.js] Failed to load workspace modules."
[INFO][2023-08-27 15:47:17] ...lsp/handlers.lua:489	"[assets/tailwind.config.js] Using bundled version of `tailwindcss`: v3.3.0"
[INFO][2023-08-27 15:47:17] ...lsp/handlers.lua:489	"[assets/tailwind.config.js] Using bundled version of `postcss`: v8.3.9"
[INFO][2023-08-27 15:47:17] ...lsp/handlers.lua:489	"[assets/tailwind.config.js] Building..."
[WARN][2023-08-27 15:47:17] ...lsp/handlers.lua:113	"The language server tailwindcss triggers a registerCapability handler despite dynamicRegistration set to false. Report upstream, this warning is harmless"

…here’s DEBUG level included:

[INFO][2023-08-27 15:46:32] .../vim/lsp/rpc.lua:661	"Starting RPC client"	{  args = { "--stdio" },  cmd = "/Users/jk/.local/share/nvim/mason/bin/tailwindcss-language-server",  extra = {    cwd = "/Users/jk/work/p17"  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  id = 1,  jsonrpc = "2.0",  method = "workspace/configuration",  params = {    items = { {        section = "tailwindCSS"      } }  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:403	"server_request: callback result"	{  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } },  status = true}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:285	"rpc.send"	{  id = 1,  jsonrpc = "2.0",  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  jsonrpc = "2.0",  method = "window/logMessage",  params = {    message = '[Global] Creating projects: [{"folder":"/Users/jk/work/p17","configPath":"/Users/jk/work/p17/assets/tailwind.config.js","isUserConfigured":false,"documentSelector":[{"pattern":"/Users/jk/work/p17/assets/tailwind.config.js","priority":0},{"pattern":"/Users/jk/work/p17/assets/**","priority":3},{"pattern":"/Users/jk/work/p17/**","priority":4}]}]',    type = 4  }}
[INFO][2023-08-27 15:46:33] ...lsp/handlers.lua:489	'[Global] Creating projects: [{"folder":"/Users/jk/work/p17","configPath":"/Users/jk/work/p17/assets/tailwind.config.js","isUserConfigured":false,"documentSelector":[{"pattern":"/Users/jk/work/p17/assets/tailwind.config.js","priority":0},{"pattern":"/Users/jk/work/p17/assets/**","priority":3},{"pattern":"/Users/jk/work/p17/**","priority":4}]}]'
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:285	"rpc.send"	{  jsonrpc = "2.0",  method = "workspace/didChangeConfiguration",  params = {    settings = {      editor = {        tabSize = 2      },      tailwindCSS = {        classAttributes = { "class", "className", "class:list", "classList", "ngClass" },        experimental = {          classRegex = { 'class:\\s*"([^"]*)"' }        },        lint = {          cssConflict = "warning",          invalidApply = "error",          invalidConfigPath = "error",          invalidScreen = "error",          invalidTailwindDirective = "error",          invalidVariant = "error",          recommendedVariantOrder = "warning"        },        validate = true      }    }  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:285	"rpc.send"	{  jsonrpc = "2.0",  method = "workspace/didChangeConfiguration",  params = {    settings = {      editor = {        tabSize = 2      },      tailwindCSS = {        classAttributes = { "class", "className", "class:list", "classList", "ngClass" },        experimental = {          classRegex = { 'class:\\s*"([^"]*)"' }        },        lint = {          cssConflict = "warning",          invalidApply = "error",          invalidConfigPath = "error",          invalidScreen = "error",          invalidTailwindDirective = "error",          invalidVariant = "error",          recommendedVariantOrder = "warning"        },        validate = true      }    }  }}
[INFO][2023-08-27 15:46:33] .../lua/vim/lsp.lua:1336	"LSP[tailwindcss]"	"server_capabilities"	{  server_capabilities = {    codeActionProvider = true,    colorProvider = true,    completionProvider = {      resolveProvider = true,      triggerCharacters = { '"', "'", "`", " ", ".", "(", "[", "!", "/", ":" }    },    documentLinkProvider = vim.empty_dict(),    hoverProvider = true,    textDocumentSync = {      change = 1,      openClose = true,      save = {        includeText = false      },      willSave = false,      willSaveWaitUntil = false    }  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  id = 3,  jsonrpc = "2.0",  method = "workspace/configuration",  params = {    items = { {        section = "tailwindCSS"      } }  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  id = 5,  jsonrpc = "2.0",  method = "workspace/configuration",  params = {    items = { {        section = "tailwindCSS"      } }  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:403	"server_request: callback result"	{  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } },  status = true}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:285	"rpc.send"	{  id = 3,  jsonrpc = "2.0",  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:403	"server_request: callback result"	{  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } },  status = true}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:285	"rpc.send"	{  id = 5,  jsonrpc = "2.0",  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  jsonrpc = "2.0",  method = "window/logMessage",  params = {    message = "[assets/tailwind.config.js] Initializing...",    type = 4  }}
[INFO][2023-08-27 15:46:33] ...lsp/handlers.lua:489	"[assets/tailwind.config.js] Initializing..."
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  jsonrpc = "2.0",  method = "window/logMessage",  params = {    message = "[assets/tailwind.config.js] Failed to load workspace modules.",    type = 4  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  jsonrpc = "2.0",  method = "window/logMessage",  params = {    message = "[assets/tailwind.config.js] Using bundled version of `tailwindcss`: v3.3.0",    type = 4  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  jsonrpc = "2.0",  method = "window/logMessage",  params = {    message = "[assets/tailwind.config.js] Using bundled version of `postcss`: v8.3.9",    type = 4  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  jsonrpc = "2.0",  method = "window/logMessage",  params = {    message = "[assets/tailwind.config.js] Building...",    type = 4  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  id = 7,  jsonrpc = "2.0",  method = "workspace/configuration",  params = {    items = { {        scopeUri = "file:///Users/jk/work/p17/lib/p17_web/controllers/bar_html/index.html.heex",        section = "tailwindCSS"      } }  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  id = 10,  jsonrpc = "2.0",  method = "workspace/configuration",  params = {    items = { {        scopeUri = "file:///Users/jk/work/p17/lib/p17_web/controllers/bar_html/index.html.heex",        section = "tailwindCSS"      } }  }}
[INFO][2023-08-27 15:46:33] ...lsp/handlers.lua:489	"[assets/tailwind.config.js] Failed to load workspace modules."
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  id = 12,  jsonrpc = "2.0",  method = "workspace/configuration",  params = {    items = { {        scopeUri = "file:///Users/jk/work/p17/lib/p17_web/controllers/bar_html/index.html.heex",        section = "tailwindCSS"      } }  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  jsonrpc = "2.0",  method = "@/tailwindCSS/clearColors",  params = { vim.NIL }}
[INFO][2023-08-27 15:46:33] ...lsp/handlers.lua:489	"[assets/tailwind.config.js] Using bundled version of `tailwindcss`: v3.3.0"
[INFO][2023-08-27 15:46:33] ...lsp/handlers.lua:489	"[assets/tailwind.config.js] Using bundled version of `postcss`: v8.3.9"
[INFO][2023-08-27 15:46:33] ...lsp/handlers.lua:489	"[assets/tailwind.config.js] Building..."
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  id = 14,  jsonrpc = "2.0",  method = "workspace/configuration",  params = {    items = { {        scopeUri = "file:///Users/jk/work/p17/lib/p17_web/controllers/bar_html/index.html.heex",        section = "tailwindCSS"      } }  }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:388	"rpc.receive"	{  jsonrpc = "2.0",  method = "@/tailwindCSS/clearColors",  params = { vim.NIL }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:403	"server_request: callback result"	{  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } },  status = true}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:285	"rpc.send"	{  id = 7,  jsonrpc = "2.0",  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } }}
[WARN][2023-08-27 15:46:33] ...lsp/handlers.lua:113	"The language server tailwindcss triggers a registerCapability handler despite dynamicRegistration set to false. Report upstream, this warning is harmless"
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:403	"server_request: callback result"	{  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } },  status = true}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:285	"rpc.send"	{  id = 10,  jsonrpc = "2.0",  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:403	"server_request: callback result"	{  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } },  status = true}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:285	"rpc.send"	{  id = 12,  jsonrpc = "2.0",  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } }}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:403	"server_request: callback result"	{  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } },  status = true}
[DEBUG][2023-08-27 15:46:33] .../vim/lsp/rpc.lua:285	"rpc.send"	{  id = 14,  jsonrpc = "2.0",  result = { {      classAttributes = { "class", "className", "class:list", "classList", "ngClass" },      experimental = {        classRegex = { 'class:\\s*"([^"]*)"' }      },      lint = {        cssConflict = "warning",        invalidApply = "error",        invalidConfigPath = "error",        invalidScreen = "error",        invalidTailwindDirective = "error",        invalidVariant = "error",        recommendedVariantOrder = "warning"      },      validate = true    } }}
1 Like

Hah! Well of course. I’m dumb. :stuck_out_tongue:

1 Like

@ohnoimdead I was missing the Tailwind LSP autocompletion. Thank you very much for sharing this!

There is a new neovim plugin for tailwind:

2 Likes

With AstroNvim v4 all of this is quite a bit easier and mostly supported out-of-the-box. I’ve got a PR up here which is still under review: feat(pack): add elixir/phoenix pack by treshenry · Pull Request #821 · AstroNvim/astrocommunity · GitHub but for anyone that wants to use this now:

  1. Install the latest AstroNvim (currently 4.1.3) per the instructions at Getting Started
  2. Remove the first line in ~/.config/nvim/lua/community.lua which looks like if true then return {} end to enable astrocommunity
  3. Copy the contents of astrocommunity/lua/astrocommunity/pack/elixir-phoenix/init.lua at main · treshenry/astrocommunity · GitHub into the plugins folder and give it a better name, i.e. ~/.config/nvim/lua/plugins/elixir-phoenix.lua

Then start nvim and everything should just work. If you want to add elixir-tools as well just copy the lazy.nvim config from GitHub - elixir-tools/elixir-tools.nvim: Neovim plugin for Elixir into the plugins folder as well, something like ~/.config/nvim/lua/plugins/elixir-tools.lua.

I’ll try and keep this post updated as things change.

1 Like

The elixir-phoenix pack was added to the astrocommunity repo making it very easy to get up and running with AstroNvim.

  1. Install the latest AstroNvim per the instructions at https://docs.astronvim.com/
  2. Remove the first line in ~/.config/nvim/lua/community.lua which looks like if true then return {} end to enable astrocommunity
  3. Add { import = "astrocommunity.pack.elixir-phoenix" }
  4. Profit :magic_wand:

Here’s what your astrocommunity.lua file might contain, for reference:

---@type LazySpec
return {
  "AstroNvim/astrocommunity",
  { import = "astrocommunity.pack.elixir-phoenix" },
  { import = "astrocommunity.pack.lua" },
  -- import/override with your plugins folder
}
2 Likes

nice, thanks @ohnoimdead for creating the astrocommunity pack.
i hope it is helpful for some of you guys