WIP: Add Tailwind CSS class auto-sort on save via custom LSP method #3

Closed
Copilot wants to merge 0 commits from copilot/update-neovim-lsp-tailwind-sort into main
Copilot commented 2026-02-08 01:11:12 +00:00 (Migrated from github.com)

Implements automatic Tailwind CSS class sorting on file save using the @/tailwindCSS/sortSelection custom method from the Tailwind CSS language server.

Changes

  • sort_tailwind_classes() helper - Scans buffer for all class and className attributes using pattern matching, requests sorting via @/tailwindCSS/sortSelection for each class string, applies sorted results respecting client offset encoding
  • LspAttach autocmd - Hooks BufWritePre when tailwindcss client attaches, using buffer-specific augroups to prevent duplicate registrations
  • Coexists with existing format-on-save and Ruff hover disable logic

Implementation

-- Scans for class attributes and requests sorting for each
local function sort_tailwind_classes(bufnr, client_id)
    local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
    local class_pattern = '(class[Nn]ame?)%s*=%s*(["\'])([^"\']*)["\']'
    
    -- Find all class attributes
    for line_num, line in ipairs(lines) do
        -- For each match, request sorting via @/tailwindCSS/sortSelection
        local params = {
            textDocument = vim.lsp.util.make_text_document_params(bufnr),
            classLists = { class_string },
        }
        local result = client.request_sync('@/tailwindCSS/sortSelection', params, TIMEOUT, bufnr)
        -- Apply sorted results
    end
end

-- Hook into save for tailwindcss buffers
vim.api.nvim_create_autocmd("LspAttach", {
    callback = function(args)
        if client.name == 'tailwindcss' then
            vim.api.nvim_create_autocmd("BufWritePre", {
                buffer = args.buf,
                callback = function() sort_tailwind_classes(args.buf, client_id) end
            })
        end
    end
})

Sorting executes before format-on-save, ensuring classes are ordered per Tailwind's recommended conventions. The implementation finds all class and className attributes (supporting both single and double quotes) and sorts each individually, applying edits in reverse order to maintain position accuracy.

Original prompt

Update the Neovim LSP configuration in x4ndr0m3d4x/dots to automatically sort Tailwind CSS classes on save using the Tailwind CSS language server. Implement a helper in nvim/lua/lsp.lua that requests the textDocument/codeAction for source.sortTailwindClasses across the whole buffer, applies any workspace edits (respecting the client offset encoding), and executes any returned commands. Hook this helper into BufWritePre when the attached LSP client is tailwindcss, so it runs for any buffer where that LSP is attached. Ensure this new hook coexists with the existing format-on-save setup and the Ruff hover disable logic.

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Implements automatic Tailwind CSS class sorting on file save using the `@/tailwindCSS/sortSelection` custom method from the Tailwind CSS language server. ## Changes - **`sort_tailwind_classes()` helper** - Scans buffer for all `class` and `className` attributes using pattern matching, requests sorting via `@/tailwindCSS/sortSelection` for each class string, applies sorted results respecting client offset encoding - **`LspAttach` autocmd** - Hooks `BufWritePre` when `tailwindcss` client attaches, using buffer-specific augroups to prevent duplicate registrations - **Coexists** with existing format-on-save and Ruff hover disable logic ## Implementation ```lua -- Scans for class attributes and requests sorting for each local function sort_tailwind_classes(bufnr, client_id) local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) local class_pattern = '(class[Nn]ame?)%s*=%s*(["\'])([^"\']*)["\']' -- Find all class attributes for line_num, line in ipairs(lines) do -- For each match, request sorting via @/tailwindCSS/sortSelection local params = { textDocument = vim.lsp.util.make_text_document_params(bufnr), classLists = { class_string }, } local result = client.request_sync('@/tailwindCSS/sortSelection', params, TIMEOUT, bufnr) -- Apply sorted results end end -- Hook into save for tailwindcss buffers vim.api.nvim_create_autocmd("LspAttach", { callback = function(args) if client.name == 'tailwindcss' then vim.api.nvim_create_autocmd("BufWritePre", { buffer = args.buf, callback = function() sort_tailwind_classes(args.buf, client_id) end }) end end }) ``` Sorting executes before format-on-save, ensuring classes are ordered per Tailwind's recommended conventions. The implementation finds all `class` and `className` attributes (supporting both single and double quotes) and sorts each individually, applying edits in reverse order to maintain position accuracy. <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > Update the Neovim LSP configuration in `x4ndr0m3d4x/dots` to automatically sort Tailwind CSS classes on save using the Tailwind CSS language server. Implement a helper in `nvim/lua/lsp.lua` that requests the `textDocument/codeAction` for `source.sortTailwindClasses` across the whole buffer, applies any workspace edits (respecting the client offset encoding), and executes any returned commands. Hook this helper into `BufWritePre` when the attached LSP client is `tailwindcss`, so it runs for any buffer where that LSP is attached. Ensure this new hook coexists with the existing format-on-save setup and the Ruff hover disable logic. </details> <!-- START COPILOT CODING AGENT SUFFIX --> *This pull request was created from Copilot chat.* > <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.
x4ndr0m3d4x (Migrated from github.com) reviewed 2026-02-08 01:11:12 +00:00
x4ndr0m3d4x commented 2026-02-08 08:11:22 +00:00 (Migrated from github.com)

@copilot Looking at the source code of the TailwindCSS' language server, the "method" to sort a selection is "@/tailwindCSS/sortSelection". Sorting the entire file has not been implemented AFAIK. The implementation needs to be able to find all the instanced of the class strings (I guess everything after HTML's "class" should be enough for now), request the sorting, and update the instance with the result.

@copilot Looking at the source code of the TailwindCSS' language server, the "method" to sort a selection is "@/tailwindCSS/sortSelection". Sorting the entire file has not been implemented AFAIK. The implementation needs to be able to find all the instanced of the class strings (I guess everything after HTML's "class" should be enough for now), request the sorting, and update the instance with the result.
Copilot commented 2026-02-08 08:13:15 +00:00 (Migrated from github.com)

@copilot Looking at the source code of the TailwindCSS' language server, the "method" to sort a selection is "@/tailwindCSS/sortSelection". Sorting the entire file has not been implemented AFAIK. The ...

Updated the implementation to use @/tailwindCSS/sortSelection method instead of code actions. The new approach:

  1. Scans the buffer for all class and className attributes using pattern matching
  2. Requests sorting for each class string individually via @/tailwindCSS/sortSelection
  3. Applies the sorted results back to the buffer in reverse order to maintain position accuracy

Fixed in commit 4eba5ef.

> @copilot Looking at the source code of the TailwindCSS' language server, the "method" to sort a selection is "@/tailwindCSS/sortSelection". Sorting the entire file has not been implemented AFAIK. The ... Updated the implementation to use `@/tailwindCSS/sortSelection` method instead of code actions. The new approach: 1. Scans the buffer for all `class` and `className` attributes using pattern matching 2. Requests sorting for each class string individually via `@/tailwindCSS/sortSelection` 3. Applies the sorted results back to the buffer in reverse order to maintain position accuracy Fixed in commit 4eba5ef.

Pull request closed

Sign in to join this conversation.
No description provided.