Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ wouldn't usually know about. The value is a list of dictionaries containing:
- `triggerCharacters`: Override the LSP server's trigger characters for
completion. This can be useful when the server obnoxiously requests completion
on every character or for example on whitespace characters.
- `settings`: optional. Default language server settings. These can be overridden
on a per-project basis by the `Settings()` function in `.ycm_extra_conf.py`
files (see below).

```json
{
Expand All @@ -298,7 +301,13 @@ wouldn't usually know about. The value is a list of dictionaries containing:
"cmdline": [ "/path/to/gopls", "-rpc.trace" ],
"filetypes": [ "go" ],
"project_root_files": [ "go.mod" ],
"triggerCharacters": [ "." ]
"triggerCharacters": [ "." ],
"settings": {
"gopls": {
"usePlaceholders": true,
"staticcheck": true
}
}
} ]
}
```
Expand Down Expand Up @@ -334,6 +343,45 @@ Or, to use an unused local port, set `port` to `*` and use `${port}` in the
When plugging in a completer in this way, the `kwargs[ 'language' ]` will be set
to the value of the `name` key, i.e. `gopls` in the above example.

##### Language Server Settings Priority

Language server settings are merged with the following priority (later overrides earlier):

1. Settings from the `settings` key in `language_server` configuration (from Vim `g:ycm_language_server` option)
2. Settings from the `ls` key returned by the `Settings()` function in
`.ycm_extra_conf.py`

This allows you to define default language server settings in your Vim configuration, and override them on a per-project basis using `.ycm_extra_conf.py`. For example:

In your Vim configuration:
```vim
let g:ycm_language_server = [
\ {
\ 'name': 'gopls',
\ 'filetypes': ['go'],
\ 'cmdline': ['/path/to/gopls'],
\ 'settings': {
\ 'hoverKind': 'SynopsisDocumentation',
\ 'gopls': {
\ 'usePlaceholders': true,
\ },
\ },
\ },
\]
```

In a project's `.ycm_extra_conf.py`:
```python
def Settings( **kwargs ):
return {
'ls': {
'gopls': {
'usePlaceholders': false, # Override the Vim default
}
}
}
```

A number of LSP completers are currently supported without `language_server`,
usch as:

Expand Down
6 changes: 6 additions & 0 deletions ycmd/completers/language_server/generic_lsp_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,9 @@ def WorkspaceConfigurationResponse( self, request ):
def GetTriggerCharacters( self, server_trigger_characters ):
return self._server_settings.get( 'triggerCharacters',
server_trigger_characters )


def DefaultSettings( self, request_data ):
settings = super().DefaultSettings( request_data ).copy()
Comment thread
puremourning marked this conversation as resolved.
Outdated
settings.update( self._server_settings.get( 'settings', {} ) )
Comment thread
Felixoid marked this conversation as resolved.
Outdated
return settings
60 changes: 60 additions & 0 deletions ycmd/tests/language_server/generic_completer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -705,3 +705,63 @@ def test_GenericLSPCompleter_SingleDiagnostics( self, app ):
} )
) } )
) )


@IsolatedYcmd( {
'language_server':
[ { 'name': 'foo',
'filetypes': [ 'foo' ],
'cmdline': [ 'node', PATH_TO_GENERIC_COMPLETER, '--stdio' ],
'settings': {
'foo.bar': 'from_vim',
'foo.baz': 'only_in_vim'
} } ] } )
def test_GenericLSPCompleter_Settings_FromLanguageServer( self, app ):
completer = handlers._server_state.GetFiletypeCompleter( [ 'foo' ] )
request = BuildRequest( filepath = TEST_FILE,
filetype = 'foo',
line_num = 1,
column_num = 1,
contents = 'test',
event_name = 'FileReadyToParse' )
app.post_json( '/event_notification', request )
WaitUntilCompleterServerReady( app, 'foo' )

# Check that settings from language_server config are used
assert_that( completer._settings.get( 'ls', {} ),
has_entries( {
'foo.bar': 'from_vim',
'foo.baz': 'only_in_vim'
} ) )


@IsolatedYcmd( {
'global_ycm_extra_conf': PathToTestFile( 'extra_confs',
'settings_extra_conf.py' ),
'language_server':
[ { 'name': 'foo',
'filetypes': [ 'foo' ],
'cmdline': [ 'node', PATH_TO_GENERIC_COMPLETER, '--stdio' ],
'settings': {
'foo.bar': 'from_vim',
'foo.baz': 'only_in_vim'
} } ] } )
def test_GenericLSPCompleter_Settings_MergeWithExtraConf( self, app ):
completer = handlers._server_state.GetFiletypeCompleter( [ 'foo' ] )
filepath = PathToTestFile( 'extra_confs', 'foo' )
request = BuildRequest( filepath = filepath,
filetype = 'foo',
line_num = 1,
column_num = 1,
contents = 'test',
event_name = 'FileReadyToParse' )
app.post_json( '/event_notification', request )
WaitUntilCompleterServerReady( app, 'foo' )

# Check that settings are merged with extra_conf overriding
assert_that( completer._settings.get( 'ls', {} ),
has_entries( {
'foo.bar': 'from_vim', # From language_server
'foo.baz': 'only_in_vim', # From language_server
'java.rename.enabled': False # From extra_conf (override)
} ) )
Loading