Skip to content

Add possibility to overwrite the languageId that is sent to the server#753

Merged
yegappan merged 2 commits intoyegappan:mainfrom
jclsn:support-custom-filetypes
Mar 17, 2026
Merged

Add possibility to overwrite the languageId that is sent to the server#753
yegappan merged 2 commits intoyegappan:mainfrom
jclsn:support-custom-filetypes

Conversation

@jclsn
Copy link
Contributor

@jclsn jclsn commented Jan 29, 2026

I am putting this PR up for discussion:

I have tried to copy a feature that nvim-lsp has, which is overwriting the languageId that is sent to the server. See https://github.com/neovim/nvim-lspconfig/blob/238583bb00770b079c68c69a860d65e5d1d8acf9/lsp/docker_language_server.lua#L14

The docker language-server supports Dockerfile and docker-compose.yml. In case a yaml is detected, you need to send a different languageId to the server. This commit provides a way to customize the languageId via a function.

This is only needed though, because in Neovim they call their sub-filetypes yaml.docker-compose, yaml.gitlab etc. and then the wrong languageId would get sent to the server. You could however just do

au BufEnter,BufRead docker-compose.yaml,docker-compose.yml set filetype=dockercompse
au BufEnter,BufRead docker-compose.yaml,docker-compose.yml set syntax=yaml

and forget about it. You would then just have to add the dockercompose filetype also to the YAML language server, so it will still pick it up, which the Neovim people also still need to do: https://github.com/neovim/nvim-lspconfig/blob/238583bb00770b079c68c69a860d65e5d1d8acf9/doc/configs.md?plain=1#L14415

The advantage of a yaml.docker-compose filetype is merely

  1. It still sources the yaml syntax file
  2. It provides a good mental model of categorizing filetypes

I wonder if we should do this. I already made the patch, so we can add the feature, but it is not strictly needed for the functionality.

It would be used like this

vim9script

augroup dockercompose_yaml
    autocmd!
    autocmd BufEnter,BufReadPre docker-compose.yaml,docker-compose.yml setfiletype dockercompose.yaml
augroup END

def GetLanguageId(): string
    if expand('%:t') =~# 'docker-compose' && &filetype =~# 'yaml'
        return 'dockercompose'
    endif
    return &filetype
enddef

g:LspAddServer ([{
    name: 'docker-language-server',
    path: 'docker-language-server',
    args: ['start', '--stdio'],
    filetype: ['dockerfile', 'dockercompose.yaml'],
    debug: v:true,
    languageId: GetLanguageId,
}])

@jclsn jclsn changed the title Add possibility to send a custom languageId to the server Add possibility to overwrite the languageId that is sent to the server Jan 29, 2026
@Konfekt
Copy link
Contributor

Konfekt commented Mar 16, 2026

Turns out this would also be of interest for https://github.com/alesbrelih/gitlab-ci-ls ; this is likely a general issue, many LSs taking care of different tools configured in yaml files

var languageId = ftype

if type(lspserver.languageId) == v:t_func
languageId = lspserver.languageId()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the patch. As a user provided function is invoked here, can you add exception handling (try-catch) here?

Copy link
Contributor Author

@jclsn jclsn Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed. I checked for all errors. Is that what you had in mind?

@yegappan
Copy link
Owner

I wonder if we should do this. I already made the patch, so we can add the feature, but it is not strictly needed for the functionality.

It makes sense to add this support. Thanks for the patch. Can you move this PR out of draft state?

@yegappan
Copy link
Owner

Can you update the help text with a description of how to set the languageId?

var languageId = ftype

if type(lspserver.languageId) == v:t_func
languageId = lspserver.languageId()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The languageId() function should take the filetype as an argument?

Copy link
Contributor Author

@jclsn jclsn Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used it like this

autocmd BufEnter,BufReadPre docker-compose.yaml,docker-compose.yml setf dockercompose.yaml

function GetLanguageId()
	if expand('%:t') =~# 'docker-compose' && &filetype =~# 'yaml'
		return 'dockercompose'
	else
		return &filetype
	endif
endfunc

let docker_ls =
		\ #{name: 'docker-language-server',
		\   path: 'docker-language-server',
		\   args: ['start', '--stdio'],
		\   filetype: ['dockerfile', 'dockercompose.yaml'],
		\   debug: 'v:true',
		\   languageId: function('GetLanguageId')
		\ }

The docker language-server supports Dockerfile and docker-compose.yml.
In case a yaml is detected, you need to send a different languageId to
the server. This commit provides a way to customize the languageId via
function.
@jclsn jclsn force-pushed the support-custom-filetypes branch 3 times, most recently from 488bff4 to 47e7a73 Compare March 16, 2026 19:56
@jclsn jclsn marked this pull request as ready for review March 16, 2026 19:56
@jclsn jclsn force-pushed the support-custom-filetypes branch from 47e7a73 to 4edcc46 Compare March 16, 2026 19:58
@jclsn
Copy link
Contributor Author

jclsn commented Mar 16, 2026

Turns out this would also be of interest for https://github.com/alesbrelih/gitlab-ci-ls ; this is likely a general issue, many LSs taking care of different tools configured in yaml files

Yeah, it could be useful for this one as well. I already asked @chrisbra if he would add a dockercompose filetype to the runtime here, but he did not like the idea I think. My approach back then was also wrong. Something like dockercompose.yaml or yaml.dockercompose etc. would be needed. In Neovim this is the design choice they took. I mean this double filetype feature exists in vim, but it's not really used in the vim-runtime so far.

@jclsn
Copy link
Contributor Author

jclsn commented Mar 16, 2026

Can you update the help text with a description of how to set the languageId?

I added a section in to the help file.

@Konfekt
Copy link
Contributor

Konfekt commented Mar 16, 2026

I dug out from vim/vim#19200

There is in :help 'filetype'

>  doc/options.txt (lines 3872-3877)
	When a dot appears in the value then this separates two filetype
	names, it should therefore not be used for a filetype.  Example:
		/* vim: set filetype=c.doxygen : */ ~
	This will use the "c" filetype first, then the "doxygen" filetype.
	This works both for filetype plugins and for syntax files.  More than
	one dot may appear.

and

au BufNewFile,BufRead docker-compose.yaml,docker-compose.yml set filetype=dockercompose.yaml

did not work for lsp as reported by @jclsn ; now the idea is that languageId can override &filetype in lsp's config?

I find the above definition of a composed file type for specific file paths as needs arise, handing them over to lsp, more straightforward than handing over a function as a parameter to languageID.

Is this a feature that composed file types do not work with lsp as reported by @jclsn , or could it be considered to make it work for those as well?

@jclsn
Copy link
Contributor Author

jclsn commented Mar 16, 2026

@Konfekt It doesn't work for you?

I just edited the examples. Things to look out for:

  1. docker-language-server works with docker-compose.yaml
  2. docker-language-server works with Dockerfile
  3. docker-language-server doesn't start on any yaml

@jclsn jclsn force-pushed the support-custom-filetypes branch from 4edcc46 to bf713f3 Compare March 16, 2026 21:25
@Konfekt
Copy link
Contributor

Konfekt commented Mar 16, 2026

Sorry for the misunderstanding; I was just musing about possible approaches and wondered why lsp does not allow for composed filetypes as you reported in that Vim issue

@jclsn
Copy link
Contributor Author

jclsn commented Mar 16, 2026

Well, you could of course separate the types by the dot. Then you would have to decide for which one to start the server for. I was about to implement this, but concluded that no hardcoded solution would cover any possible case. What if you have three filetypes? What if the logic needs to be entirely differnt? It's best to provide a way to add a function that can take of this.

@jclsn jclsn force-pushed the support-custom-filetypes branch from bf713f3 to 4986ac6 Compare March 16, 2026 21:54
Provides a small example on how to configure the custom languageId
@jclsn jclsn force-pushed the support-custom-filetypes branch from 4986ac6 to de6d0da Compare March 16, 2026 21:55
@yegappan
Copy link
Owner

Thanks

@yegappan yegappan merged commit 60342d1 into yegappan:main Mar 17, 2026
2 checks passed
@Konfekt
Copy link
Contributor

Konfekt commented Mar 17, 2026

Well, you could of course separate the types by the dot. Then you would have to decide for which one to start the server for. I was about to implement this, but concluded that no hardcoded solution would cover any possible case. What if you have three filetypes? What if the logic needs to be entirely differnt? It's best to provide a way to add a function that can take of this.

Yes, makes sense, and passing a function is always the most flexible. In Vim9 syntax, as in your help text, passing a function is also pretty straightforward. Adding a new (composed) file type entails decisions about its proper setup (ftplugin/syntax), so overriding languageID is the most precise. Thank you!

@Shane-XB-Qian
Copy link
Contributor

Shane-XB-Qian commented Mar 17, 2026 via email

@Konfekt
Copy link
Contributor

Konfekt commented Mar 17, 2026

dockercompose was a pre-defined identity in 'docker-language-server'

Yes, it would be convenient to have a list of these identities for the various LSs. I guess for, say https://github.com/alesbrelih/gitlab-ci-ls#integration-with-neovim it would be gitlabci, but it's not so clear where to find the correct language ID

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants