Auto-completion in Vim does not work for certain file-types
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 50/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- vim
- Domain
- tooling
Research direction
Start by tracing the Vim-side LSP initialize lifecycle message and compare its parameters with the Neovim example in the issue, especially client capabilities. Reproduce completion with vscode-css-language-server or another VSCode language server, then verify that completion works in Vim for the affected file types without breaking existing LSP behavior.
Written by the indexing model from the issue text.
Description
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
- Either:
- 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']
- Dominant language
- Vim Script
- Stars
- 14k
- Forks
- 1.5k
- PR merge metrics
- No merged PRs in 30d
Getting set up
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dense-analysis/ale
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
dense-analysis/ale#5181 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
dense-analysis/ale#5180 · 1 comment ·
-
new tool
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
dense-analysis/ale#5176 ·
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 75/100
dense-analysis/ale#5174 ·
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
dense-analysis/ale#5158 ·
All issues in dense-analysis/ale
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
ScoopInstaller/Extras#19364 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
osrep/Runes2P.jl#279 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
1.3 bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
normalizePropName strips `#` characters from Figma property names instead of only the `#id` suffixOpen
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
figma/code-connect#419 ·