dense-analysis / dense-analysis/ale
Auto-completion in Vim does not work for certain file-types
- Dominant language
- Vim Script
- Stars
- 14k
- Forks
- 1.5k
- Avg merge
- 17h 49m
- Merged PRs (30d)
- 1
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](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initializeParams), 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](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#snippet_syntax) 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](https://github.com/hrsh7th/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']
```
Contributor guide
Assessment
This issue has not been assessed yet.