Skip to content

Auto-completion in Vim does not work for certain file-types #5136

@letorbi

Description

@letorbi

Information

VIM version

VIM - Vi IMproved 9.2 (2026 Feb 14, compiled May 22 2026 18:43:08)
Included patches: 1-511
NVIM v0.12.2
Build type: RelWithDebInfo

Operating System:

Linux mememe 7.0.10-arch1-1 #1 SMP PREEMPT_DYNAMIC Sat, 23 May 2026 14:21:20 +0000 x86_64 GNU/Linux

What went wrong

During my investigation for #5130 I discovered that auto-completion for CSS files with vscode-css-language-server does not work in Vim, but works in Neovim. Further tests showed that the auto-completion with any VSCode language server works only in Neovim.

I assume that other language servers are affected as well, but I haven't tested any further.

Possible solution

I was able to track the problem down to the parameters of the initalize lifecycle message, which is sent to the language server after the process has been started. These differ significantly between Vim and Neovim:

Vim initialize call
{
    "method": "initialize",
    "jsonrpc": "2.0",
    "id": 1,
    "params": {
        "initializationOptions": {},
        "rootUri": "file:///home/letorbi/Projects/Frauenhaus/Repositories/flora",
        "capabilities": {
            "workspace": {
                "workspaceFolders": false,
                "configuration": false,
                "symbol": {
                    "dynamicRegistration": false
                },
                "applyEdit": false,
                "didChangeConfiguration": {
                    "dynamicRegistration": false
                }
            },
            "textDocument": {
                "documentSymbol": {
                    "dynamicRegistration": false,
                    "hierarchicalDocumentSymbolSupport": false
                },
                "references": {
                    "dynamicRegistration": false
                },
                "publishDiagnostics": {
                    "relatedInformation": true
                },
                "rename": {
                    "dynamicRegistration": false
                },
                "completion": {
                    "completionItem": {
                        "snippetSupport": false,
                        "commitCharactersSupport": false,
                        "preselectSupport": false,
                        "deprecatedSupport": false,
                        "documentationFormat": ["plaintext", "markdown"]
                    },
                    "contextSupport": false,
                    "dynamicRegistration": false
                },
                "synchronization": {
                    "didSave": true,
                    "willSaveWaitUntil": false,
                    "willSave": false,
                    "dynamicRegistration": false
                },
                "codeAction": {
                    "codeActionLiteralSupport": {
                        "codeActionKind": {
                            "valueSet": []
                        }
                    },
                    "dynamicRegistration": false
                },
                "diagnostic": {
                    "dynamicRegistration": true,
                    "relatedDocumentSupport": true
                },
                "typeDefinition": {
                    "dynamicRegistration": false
                },
                "hover": {
                    "dynamicRegistration": false,
                    "contentFormat": ["plaintext", "markdown"]
                },
                "implementation": {
                    "dynamicRegistration": false,
                    "linkSupport": false
                },
                "definition": {
                    "dynamicRegistration": false,
                    "linkSupport": false
                }
            }
        },
        "rootPath": "/home/letorbi/Projects/Frauenhaus/Repositories/flora",
        "processId": null
    }
}
Neoim initialize call
{
    "params": {
        "workspaceFolders": [
            {
                "name": "/home/letorbi/Projects/Frauenhaus/Repositories/flora",
                "uri": "file:///home/letorbi/Projects/Frauenhaus/Repositories/flora"
            }
        ],
        "capabilities": {
            "window": {
                "showDocument": {
                    "support": true
                },
                "workDoneProgress": true,
                "showMessage": {
                    "messageActionItem": {
                        "additionalPropertiesSupport": true
                    }
                }
            },
            "general": {
                "positionEncodings": ["utf-8", "utf-16", "utf-32"]
            },
            "workspace": {
                "fileOperations": {
                    "dynamicRegistration": false,
                    "didCreate": false,
                    "willCreate": false,
                    "didRename": false,
                    "willRename": false,
                    "didDelete": false,
                    "willDelete": false
                },
                "configuration": true,
                "didChangeConfiguration": {
                    "dynamicRegistration": false
                },
                "workspaceFolders": true,
                "applyEdit": true,
                "workspaceEdit": {
                    "resourceOperations": ["rename", "create", "delete"],
                    "normalizesLineEndings": true,
                    "changeAnnotationSupport": {
                        "groupsOnLabel": true
                    }
                },
                "inlayHint": {
                    "refreshSupport": true
                },
                "symbol": {
                    "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
                        ]
                    },
                    "dynamicRegistration": false
                },
                "codeLens": {
                    "refreshSupport": true
                },
                "didChangeWatchedFiles": {
                    "relativePatternSupport": true,
                    "dynamicRegistration": false
                },
                "semanticTokens": {
                    "refreshSupport": true
                },
                "diagnostics": {
                    "refreshSupport": true
                }
            },
            "textDocument": {
                "synchronization": {
                    "willSaveWaitUntil": true,
                    "didSave": true,
                    "dynamicRegistration": false,
                    "willSave": true
                },
                "onTypeFormatting": {
                    "dynamicRegistration": false
                },
                "documentLink": {
                    "tooltipSupport": false,
                    "dynamicRegistration": false
                },
                "linkedEditingRange": {
                    "dynamicRegistration": false
                },
                "inlineCompletion": {
                    "dynamicRegistration": false
                },
                "typeDefinition": {
                    "linkSupport": true
                },
                "references": {
                    "dynamicRegistration": false
                },
                "implementation": {
                    "linkSupport": true
                },
                "codeLens": {
                    "resolveSupport": {
                        "properties": ["command"]
                    },
                    "dynamicRegistration": false
                },
                "foldingRange": {
                    "foldingRangeKind": {
                        "valueSet": ["comment", "imports", "region"]
                    },
                    "foldingRange": {
                        "collapsedText": true
                    },
                    "lineFoldingOnly": true,
                    "dynamicRegistration": false
                },
                "colorProvider": {
                    "dynamicRegistration": true
                },
                "selectionRange": {
                    "dynamicRegistration": false
                },
                "declaration": {
                    "linkSupport": true
                },
                "definition": {
                    "dynamicRegistration": true,
                    "linkSupport": true
                },
                "formatting": {
                    "dynamicRegistration": true
                },
                "rangeFormatting": {
                    "rangesSupport": true,
                    "dynamicRegistration": true
                },
                "callHierarchy": {
                    "dynamicRegistration": false
                },
                "documentSymbol": {
                    "hierarchicalDocumentSymbolSupport": true,
                    "tagSupport": {
                        "valueSet": [1]
                    },
                    "dynamicRegistration": false,
                    "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
                        ]
                    }
                },
                "publishDiagnostics": {
                    "tagSupport": {
                        "valueSet": [1, 2]
                    },
                    "dataSupport": true,
                    "relatedInformation": true
                },
                "rename": {
                    "prepareSupport": true,
                    "honorsChangeAnnotations": true,
                    "dynamicRegistration": true
                },
                "documentHighlight": {
                    "dynamicRegistration": false
                },
                "inlayHint": {
                    "resolveSupport": {
                        "properties": [
                            "textEdits",
                            "tooltip",
                            "location",
                            "command"
                        ]
                    },
                    "dynamicRegistration": true
                },
                "diagnostic": {
                    "relatedDocumentSupport": true,
                    "dynamicRegistration": true,
                    "tagSupport": {
                        "valueSet": [1, 2]
                    },
                    "dataSupport": true,
                    "relatedInformation": true
                },
                "signatureHelp": {
                    "signatureInformation": {
                        "documentationFormat": ["markdown", "plaintext"],
                        "activeParameterSupport": true,
                        "noActiveParameterSupport": true,
                        "parameterInformation": {
                            "labelOffsetSupport": true
                        }
                    },
                    "dynamicRegistration": false
                },
                "hover": {
                    "contentFormat": ["markdown", "plaintext"],
                    "dynamicRegistration": true
                },
                "completion": {
                    "dynamicRegistration": false,
                    "contextSupport": true,
                    "completionItem": {
                        "tagSupport": {
                            "valueSet": [1]
                        },
                        "snippetSupport": true,
                        "commitCharactersSupport": false,
                        "preselectSupport": false,
                        "deprecatedSupport": true,
                        "documentationFormat": ["markdown", "plaintext"],
                        "insertReplaceSupport": true,
                        "labelDetailsSupport": true,
                        "resolveSupport": {
                            "properties": [
                                "additionalTextEdits",
                                "command",
                                "documentation"
                            ]
                        }
                    },
                    "completionItemKind": {
                        "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
                        ]
                    },
                    "completionList": {
                        "itemDefaults": [
                            "editRange",
                            "insertTextFormat",
                            "insertTextMode",
                            "data"
                        ]
                    }
                },
                "semanticTokens": {
                    "serverCancelSupport": false,
                    "augmentsSyntaxTokens": true,
                    "dynamicRegistration": false,
                    "formats": ["relative"],
                    "tokenModifiers": [
                        "declaration",
                        "definition",
                        "readonly",
                        "static",
                        "deprecated",
                        "abstract",
                        "async",
                        "modification",
                        "documentation",
                        "defaultLibrary"
                    ],
                    "requests": {
                        "range": true,
                        "full": {
                            "delta": true
                        }
                    },
                    "tokenTypes": [
                        "namespace",
                        "type",
                        "class",
                        "enum",
                        "interface",
                        "struct",
                        "typeParameter",
                        "parameter",
                        "variable",
                        "property",
                        "enumMember",
                        "event",
                        "function",
                        "method",
                        "macro",
                        "keyword",
                        "modifier",
                        "comment",
                        "string",
                        "number",
                        "regexp",
                        "operator",
                        "decorator"
                    ],
                    "overlappingTokenSupport": true,
                    "multilineTokenSupport": true
                },
                "codeAction": {
                    "isPreferredSupport": true,
                    "resolveSupport": {
                        "properties": ["edit", "command"]
                    },
                    "dynamicRegistration": true,
                    "honorsChangeAnnotations": true,
                    "disabledSupport": true,
                    "dataSupport": true,
                    "codeActionLiteralSupport": {
                        "codeActionKind": {
                            "valueSet": [
                                "",
                                "quickfix",
                                "refactor",
                                "refactor.extract",
                                "refactor.inline",
                                "refactor.rewrite",
                                "source",
                                "source.organizeImports"
                            ]
                        }
                    }
                }
            }
        },
        "processId": 82329,
        "clientInfo": {
            "version": "0.12.2+v0.12.2",
            "name": "Neovim"
        },
        "rootUri": "file:///home/letorbi/Projects/Frauenhaus/Repositories/flora",
        "rootPath": "/home/letorbi/Projects/Frauenhaus/Repositories/flora",
        "trace": "off",
        "initializationOptions": {},
        "workDoneToken": "1"
    },
    "id": 1,
    "method": "initialize",
    "jsonrpc": "2.0"
}

The problem seems to be that Vim/ALE does not report support for completion snippets to the language server, while Neovim/ALE does.

A fix would be as easy as changing params.textDocument.completion.completionItem.snippetSupport from false to true, to activate auto-completion in Vim as well. After doing that, the auto-completion works in Vim exactly the same way as it does in Neovim.

However, I would like to discuss this before creating a pull request. The reason for this is, that Vim/ALE does not seem to have the capabilities for full snippet support, so telling the language server that snippet support is available is a bit of a "fake it till you make it" approach. On the other hand Neovim/ALE does not seem to fully support snippets as well, and the user experience with the current state is at least IMHO good enough to justify setting snippetSupport to true.

Furthermore it might be desirable to streamline the behaviour of Vim and Neovim by sending exactly the same initialization parameters in Vim as in Neovim. This might eliminate other differences in the LSP support between both editors, but could also trigger unwanted side-effects.

Therefore I would like to have the maintainers' opinion(s) on the following questions:

  • Shall Vim/ALE tell the language server it has snippet support even though the support is actually limited?
  • Shall Vim/ALE send the same initialization parameters to the language server as Neovim/ALE?

Reproducing the bug

  • Install Vim and Neovim
  • Install ALE for both
  • Install vscode-langservers-extracted globally
  • Configure ALE autocompletion
    • Either: autocmd FileType * setlocal omnifunc=ale#completion#OmniFunc
    • Or: let g:ale_completion_enabled = 1
  • Open a CSS file in Vim
    • Test auto-completion
    • Nothing happens
  • Open a CSS file in Neovim
    • Test auto-completion
    • Completion works

:ALEInfo (Vim)

Expand
 Current Filetype: css
Available Linters: ['cspell', 'csslint', 'fecs', 'stylelint', 'vscodecss']
  Enabled Linters: ['cspell', 'csslint', 'fecs', 'stylelint', 'vscodecss']
  Ignored Linters: []
 Suggested Fixers:
  'biome' - Fix JavaScript and TypeScript using biome.
  'css-beautify' - Format CSS using css-beautify from js-beautify.
  'fecs' - Apply fecs format to a file.
  'prettier' - Apply prettier to a file.
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'replace_emdash' - Replace em dash with -- ASCII characters.
  'stylelint' - Fix stylesheet files using stylelint --fix.
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
 
 Linter Variables:
" Press Space to read :help for a setting
let g:ale_css_stylelint_executable = 'stylelint'
let g:ale_css_stylelint_options = ''
let g:ale_css_stylelint_use_global = 0
 
 Global Variables:
" Press Space to read :help for a setting
let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = v:false
let g:ale_command_wrapper = ''
let g:ale_completion_delay = v:null
let g:ale_completion_enabled = v:false
let g:ale_completion_max_suggestions = v:null
let g:ale_disable_lsp = 'auto'
let g:ale_echo_cursor = v:true
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = v:false
let g:ale_fixers = {}
let g:ale_history_enabled = v:true
let g:ale_info_default_mode = 'preview'
let g:ale_history_log_output = v:true
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = v:true
let g:ale_lint_on_filetype_changed = v:true
let g:ale_lint_on_insert_leave = v:true
let g:ale_lint_on_save = v:true
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linter_aliases = {}
let g:ale_linters = {}
let g:ale_linters_explicit = v:false
let g:ale_linters_ignore = {}
let g:ale_list_vertical = v:false
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = v:false
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_root = {}
let g:ale_set_balloons = v:false
let g:ale_set_highlights = v:true
let g:ale_set_loclist = v:true
let g:ale_set_quickfix = v:false
let g:ale_set_signs = v:true
let g:ale_sign_column_always = v:false
let g:ale_sign_error = 'E'
let g:ale_sign_info = 'I'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = 'E'
let g:ale_sign_style_warning = 'W'
let g:ale_sign_warning = 'W'
let g:ale_sign_highlight_linenrs = v:false
let g:ale_type_map = {}
let g:ale_use_neovim_diagnostics_api = v:false
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 'all'
let g:ale_warn_about_trailing_blank_lines = v:true
let g:ale_warn_about_trailing_whitespace = v:true
 
  Command History:

(executable check - failure) cspell
(executable check - failure) csslint
(executable check - failure) fecs
(executable check - failure) stylelint
(executable check - success) vscode-css-language-server
(started) ['/bin/bash', '-c', '''vscode-css-language-server'' --stdio']

:ALEInfo (Neovim)

Expand
 Current Filetype: css
Available Linters: ['cspell', 'csslint', 'fecs', 'stylelint', 'vscodecss']
  Enabled Linters: ['cspell', 'csslint', 'fecs', 'stylelint', 'vscodecss']
  Ignored Linters: []
 Suggested Fixers:
  'biome' - Fix JavaScript and TypeScript using biome.
  'css-beautify' - Format CSS using css-beautify from js-beautify.
  'fecs' - Apply fecs format to a file.
  'prettier' - Apply prettier to a file.
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'replace_emdash' - Replace em dash with -- ASCII characters.
  'stylelint' - Fix stylesheet files using stylelint --fix.
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
 
 Linter Variables:
" Press Space to read :help for a setting
let g:ale_css_stylelint_executable = 'stylelint'
let g:ale_css_stylelint_options = ''
let g:ale_css_stylelint_use_global = 0
 
 Global Variables:
" Press Space to read :help for a setting
let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = v:false
let g:ale_command_wrapper = ''
let g:ale_completion_delay = v:null
let g:ale_completion_enabled = v:false
let g:ale_completion_max_suggestions = v:null
let g:ale_disable_lsp = 'auto'
let g:ale_echo_cursor = v:true
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = v:false
let g:ale_fixers = {}
let g:ale_history_enabled = v:true
let g:ale_info_default_mode = 'preview'
let g:ale_history_log_output = v:true
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = v:true
let g:ale_lint_on_filetype_changed = v:true
let g:ale_lint_on_insert_leave = v:true
let g:ale_lint_on_save = v:true
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linter_aliases = {}
let g:ale_linters = {}
let g:ale_linters_explicit = v:false
let g:ale_linters_ignore = {}
let g:ale_list_vertical = v:false
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = v:false
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_root = {}
let g:ale_set_balloons = v:false
let g:ale_set_highlights = v:true
let g:ale_set_loclist = v:true
let g:ale_set_quickfix = v:false
let g:ale_set_signs = v:true
let g:ale_sign_column_always = v:false
let g:ale_sign_error = 'E'
let g:ale_sign_info = 'I'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = 'E'
let g:ale_sign_style_warning = 'W'
let g:ale_sign_warning = 'W'
let g:ale_sign_highlight_linenrs = v:false
let g:ale_type_map = {}
let g:ale_use_neovim_diagnostics_api = v:false
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 'all'
let g:ale_warn_about_trailing_blank_lines = v:true
let g:ale_warn_about_trailing_whitespace = v:true
 
  Command History:

(executable check - failure) cspell
(executable check - failure) csslint
(executable check - failure) fecs
(executable check - failure) stylelint
(executable check - success) vscode-css-language-server
(started) ['/bin/bash', '-c', '''vscode-css-language-server'' --stdio']

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions