O YCMD é um servidor que fornece APIs para conclusão de código e outros casos de uso de compreensão de código, como comandos semânticos do GoTo (e outros). Para certos arquivos, o YCMD também pode fornecer erros de diagnóstico e avisos.
O YCMD foi originalmente parte da base de código do YouCompleteme, mas foi dividido em um projeto separado para que possa ser usado em editores que não sejam o VIM.
Verifique a documentação da API se você deseja implementar um cliente. Uma boa maneira de aprender a interagir com o YCMD é lendo (e executando) o arquivo example_client.py . Consulte o ReadMe para obter a pasta Exemplos para obter detalhes sobre como executar o cliente de exemplo.
Sinta -se à vontade para enviar uma solicitação de tração adicionando um link ao seu cliente aqui, se você construiu um.
Se você deseja desenvolver YCMD, consulte as instruções para executar os testes.
Isso é tudo para o Ubuntu Linux. Detalhes sobre a execução do YCMD em outros sistemas operacionais podem ser encontrados nas instruções do YCM (ignore as peças específicas do VIM). Observe que o YCMD é executado no Python 3.8.0+.
Primeiro, instale as dependências mínimas:
sudo apt install build-essential cmake python3-dev
Em seguida, instale as dependências específicas do idioma que você precisa:
sudo apt install golang-go for go.sudo apt install npm para javascript e datilografript.sudo apt install mono-devel para c#.sudo apt install openjdk-8-jre para java.Ao clonar pela primeira vez o repositório, você precisará atualizar os submódulos:
git submodule update --init --recursive
Em seguida, execute python3 build.py --all ou qualquer um dos completores específicos listados pelo python3 build.py --help . Isso deve fazer você ir.
Para obter instruções mais detalhadas sobre a criação de YCMD, consulte as instruções do YCM (ignore as peças específicas do VIM).
n .x-ycm-hmac HTTP. O HMAC é calculado a partir do segredo compartilhado passado para o servidor na inicialização e o corpo de solicitação/resposta. O algoritmo Digest é SHA-256. O servidor também incluirá o HMAC em suas respostas; Você deve verificar isso antes de usar a resposta. Consulte example_client.py para ver como é feito.Existem vários motores de conclusão no YCMD. O mais básico é um complicado baseado em identificador que coleta todos os identificadores no arquivo fornecido na solicitação de conclusão, outros arquivos do mesmo FileType que foram fornecidos anteriormente e quaisquer arquivos de tags produzidos pelos CTAGs. Este motor não é semantic.
Existem também vários motores semânticos no YCM. Há o Completor de Clangd que oferece conclusão semântica para os idiomas da família C. Há também uma completadora baseada em Jedi para conclusão semântica para o Python, uma completadora baseada em omnisharp para C#, uma completadora baseada em Gopls para GO (usando GOPLs para pular para definições), um servidor baseado em TSServer para Javascript e Typencript, um servidor JDT.LS. Mais será adicionado com o tempo.
Também existem outros mecanismos de conclusão, como o FilePath Completer (parte do identificador Completer).
O servidor detectará automaticamente qual mecanismo de conclusão seria o melhor em qualquer situação. Ocasionalmente, consulta vários deles ao mesmo tempo, mescla as saídas e apresenta os resultados.
Os motores semânticos são acionados somente depois que os "gatilhos" semânticos são inseridos no código. Se a solicitação recebida mostrar que o cursor do usuário está após o último caractere em string foo; foo. Em um arquivo C#, isso acionaria o mecanismo semântico para examinar os membros do foo porque . é um gatilho semântico padrão para C# (os gatilhos podem ser alterados dinamicamente). Se o texto fosse string foo; foo.zoo , a conclusão semântica ainda seria acionada (o gatilho está por trás da palavra zoo que o usuário está digitando) e os resultados seriam filtrados com a consulta zoo .
A conclusão semântica também pode ser forçada pela configuração force_semantic: true nos dados JSON para a solicitação de conclusão, mas você deve fazer isso apenas se o usuário solicitar explicitamente a conclusão semântica com um atalho de teclado ; Caso contrário, deixe o YCMD decidir quando usar qual mecanismo.
A razão pela qual a conclusão semântica nem sempre é usada, mesmo quando disponível, porque os motores semânticos podem ser lentos e, como na maioria das vezes, o usuário não precisa de conclusão semântica.
Existem dois casos de uso principais para conclusão de código:
O primeiro caso de uso é o mais comum e é trivialmente abordado com o mecanismo de conclusão do identificador (que btw está abrindo rápido). O segundo precisa de conclusão semântica.
Uma coisa crítica a observar é que a filtragem de conclusão não se baseia na entrada de um prefixo de string da conclusão (mas isso também funciona). A entrada precisa ser uma correspondência subsequente de uma conclusão. Esta é uma maneira chique de dizer que qualquer caractere de entrada precisa estar presente em uma string de conclusão na ordem em que aparecem na entrada. Portanto, abc é uma subseqüência de xaybgc , mas não de xbyxaxxc .
O filtro subsequente remove quaisquer conclusões que não correspondam à entrada, mas o sistema de classificação entra em ação. Está um pouco envolvido, mas, aproximadamente falando, as correspondências subseqüentes de "limite de palavras" (WB) são "valores" mais do que as partidas não-WB. Com efeito, isso significa que, dada uma entrada de "gua", a conclusão "getUserAccount" seria classificada mais alta na lista do que a conclusão "fooGuxa" (ambas as correspondências subseqüentes). Um personagem de limite de palavras são todos caracteres de capital, caracteres precedidos por um sublinhado e o personagem da primeira letra na sequência de conclusão.
Se o servidor não tiver recebido nenhum pedido por um tempo (controlado pelo sinalizador --idle_suicide_seconds YCMD), ele se desligará. Isso é útil para casos em que o processo que iniciou o YCMD morre sem dizer ao YCMD para morrer também ou se YCMD pendurar (isso deve ser extremamente raro).
Se você estiver implementando um cliente para o YCMD, verifique se você tem algum tipo de encadeamento de fundo de Keep-Alive que periodicamente coloca YCMD (basta chamar o manipulador /healthy , embora qualquer manipulador o face).
Você também pode desligar isso passando --idle_suicide_seconds=0 , embora isso não seja recomendado.
Durante a startup, o YCMD tenta carregar a biblioteca ycm_core e sai com um dos seguintes códigos de retorno, se não for malsucedido:
ycm_core ;ycm_core está desatualizada. Você pode fornecer configurações para YCMD na inicialização do servidor. Há um arquivo default_settings.json que você pode ajustar. Consulte a seção Opções no Guia do Usuário do YCM para obter uma descrição sobre o que cada opção faz. Passe o caminho para o arquivo de configurações modificado para YCMD como um --options_file=/path/to/file Sinalizador. Observe que você deve definir a configuração hmac_secret (codifique o valor com base64). Como o arquivo que você está passando contém um token secreto, verifique se você está criando o arquivo temporário de uma maneira segura (a chamada do sistema linux mkstemp() é uma boa idéia; use algo semelhante para outros sistemas operacionais).
Depois de iniciar, o YCMD excluirá o arquivo de configurações que você forneceu depois de lê -lo.
O arquivo de configurações é algo que seu editor deve produzir com base nos valores que seu usuário configurou. Há também um arquivo extra ( .ycm_extra_conf.py ) que seu usuário deve fornecer para configurar certos completores semânticos. Mais informações sobre ele também podem ser encontradas na seção correspondente do Guia do Usuário do YCM.
.ycm_extra_conf.py Especificação O módulo .ycm_extra_conf.py pode definir as seguintes funções:
Settings( **kwargs ) Esta função permite que os usuários configurem o idioma com base no projeto ou globalmente. Atualmente, é exigido pelo Completor Completo e Opcional baseado em Libclang e para outros completistas. Os seguintes argumentos podem ser recuperados do dicionário kwargs e são comuns a todos os completores:
language : um identificador do Completor que chamou a função. Seu valor é python para o Python Completer e cfamily para o C-Family Completer. Este argumento é útil para configurar vários compensadores de uma só vez. Por exemplo:
def Settings ( ** kwargs ):
language = kwargs [ 'language' ]
if language == 'cfamily' :
return {
# Settings for the libclang and clangd-based completer.
}
if language == 'python' :
return {
# Settings for the Python completer.
}
return {} filename : caminho absoluto do arquivo atualmente editado.
client_data : Quaisquer dados adicionais fornecidos pelo aplicativo cliente. Consulte a documentação YouCompleteme para um exemplo.
O valor de retorno é um dicionário cujo conteúdo depende do Completor.
Os servidores LSP geralmente suportam a configuração do usuário por meio da solicitação inicial. Eles geralmente são apresentados como opções na interface do usuário. O YCMD suporta isso usando o .ycm_extra_conf.py , permitindo que o usuário especifique o dicionário exato de configurações que são passadas na mensagem inicial do servidor. Essas opções são devolvidas das Settings sob a tecla ls . O dicionário Python é convertido em JSON e incluído literalmente na solicitação inicializada do LSP. Para determinar o conjunto de opções para um servidor, consulte a documentação ou o arquivo package.json do servidor. Um objeto config_sections é um dicionário cujas teclas são "seções" e os valores são peças de configurações (geralmente encontradas no objeto ls ) correspondentes a essas seções. Isso é ainda mais indispecificado e requer tentativa e erro para fazê -lo funcionar. É opcional e só útil se você ativar explicitamente o suporte workspace/configuration .
Exemplo de configuração LSP:
def Settings ( ** kwargs ):
if kwargs [ 'language' ] == 'java' :
return { 'ls' : { 'java.rename.enabled' : False },
# `config_sections` is not used for java...
'config_sections' : { 'section0' : {} } Além disso, o YCMD pode usar qualquer servidor de idiomas, dado um tipo de arquivo e uma linha de comando. Uma opção de usuário language_server pode ser usada para conectar um servidor LSP YCMD normalmente não sabia. O valor é uma lista de dicionários contendo:
name : A sequência representando o nome do servidorcmdline : a lista que representa a linha de comando para executar o servidor (opcional; obrigatório se a porta não especificada)port : opcional. Se especificado, uma conexão TCP é usada nesta porta. Se definido como * , uma porta Locall não utilizada será selecionada e aproveitada no cmdline como ${port} (veja os exemplos abaixo).filetypes : Lista de Filetyes suportados.project_root_files : informa ao YCMD quais arquivos indicam o Project Root.capabilities' : substitui os recursos LSP padrão do YCMD.workspace/configuration , verifique os detalhes do Conf Extra, relevantes para os servidores LSP.additional_workspace_dirs : Especifica espaços de trabalho estaticamente conhecidos que devem estar abertos na inicialização do servidor LSP.triggerCharacters : Substitua os caracteres de gatilho do servidor LSP para conclusão. Isso pode ser útil quando o servidor solicita a conclusão de todos os caracteres ou, por exemplo, em caracteres de espaço em branco. {
"language_server" : [ {
"name" : " gopls " ,
"cmdline" : [ " /path/to/gopls " , " -rpc.trace " ],
"filetypes" : [ " go " ],
"project_root_files" : [ " go.mod " ],
"triggerCharacters" : [ " . " ]
} ]
}Ou, para usar uma conexão TCP:
{
"language_server" : [ {
"name" : " godot " ,
"port" : " 6008 " ,
"filetypes" : [ " gdscript " ]
} ]
} Ou, para usar uma porta local não utilizada, defina port como * e use ${port} na cmdline :
{
"language_server" : [ {
"name" : " someserver " ,
"cmdline" : [ " /path/to/some/server " , " --port " , " ${port} " ],
"port" : " * " ,
"filetypes" : [ " somethign " ],
"project_root_files" : [ " somethingfile " ]
} ]
} Ao conectar um complicado dessa maneira, o kwargs[ 'language' ] será definido para o valor da tecla name , ou seja, gopls no exemplo acima.
Atualmente, vários completistas do LSP são suportados sem language_server , USCH como:
Também é possível substituir o diretório raiz, com project_directory .
def Settings ( ** kwargs ):
return { 'project_directory' : 'src/' } # The path may be absolute as well.NOTA: Se um Complet baseado em LSP estiver configurado para um idioma que é suportado "embutido", ele substituirá o suporte interno.
A função Settings é chamada pelos completores baseados em Libclang e Clangd para que os sinalizadores do compilador usem ao compilar o arquivo atual. O caminho absoluto deste arquivo é acessível sob a chave filename do dicionário kwargs .
O valor de retorno esperado por ambos os concorrentes é um dicionário que contém os seguintes itens:
flags : (obrigatório para Libclang, opcional para Clangd) Uma lista de sinalizadores do compilador.
include_paths_relative_to_dir : (Opcional) O diretório ao qual os caminhos incluídos na lista de sinalizadores são relativos. Padrão para YCMD Working Directory para o diretório da Libclang Completer e .ycm_extra_conf.py para o Clangd Completer.
do_cache : (opcional) Um booleano indicando se o resultado dessa chamada (ou seja, a lista de sinalizadores) deve ser armazenada em cache para esse nome de arquivo. Padrões para True . Se não tiver certeza, o padrão está quase sempre correto.
O Completer, com sede em Libclang, também suporta os seguintes itens:
override_filename : (opcional) Uma string indicando o nome do arquivo para analisar como a unidade de tradução para o nome do arquivo fornecido. Esse recurso bastante avançado permite projetos que usam uma compilação de 'unity' ou para arquivos de cabeçalho que dependem de outros incluem em outros arquivos.
flags_ready : (Opcional) Um booleano indicando que os sinalizadores devem ser usados. Padrões para True . Se não tiver certeza, o padrão está quase sempre correto.
Um exemplo mínimo que simplesmente retorna uma lista de sinalizadores é:
def Settings ( ** kwargs ):
return {
'flags' : [ '-x' , 'c++' ]
} A configuração para o subcomando Format pode ser especificada com um conferling extra para o Subserver Java e para o Subserver TypeScript. As opções do formatador podem ser encontradas abaixo:
Esses servidores suportam opções de formatação personalizada a serem fornecidas de uma maneira diferente do resto. Para esse fim, a função Settings pode retornar uma propriedade formatter .
Um exemplo da configuração do formatador seria:
def Settings ( ** kwargs ):
return {
'formatting_options' : {
'org.eclipse.jdt.core.formatter.lineSplit' : 30 ,
}
} A função Settings permite que os usuários especifiquem o intérprete Python e o sys.path usado pelo Complet para fornecer conclusão e compreensão de código. Nenhum argumento adicional é aprovado.
O valor de retorno esperado pelo Completor é um dicionário que contém os seguintes itens:
interpreter_path : (opcional) caminho para o intérprete Python. ~ e variáveis ambientais no caminho são expandidas. Se não for um caminho absoluto, ele será pesquisado através do PATH .
sys_path : (opcional) Lista de caminhos antecipados ao sys.path .
Exemplo de uso:
def Settings ( ** kwargs ):
return {
'interpreter_path' : '~/project/virtual_env/bin/python' ,
'sys_path' : [ '~/project/third_party/module' ]
}PythonSysPath( **kwargs )Opcional para suporte ao Python.
Esta função permite uma personalização adicional do sys.path Pathon Path. Seus parâmetros são os itens possíveis retornados pela função Settings para o Python Completer:
interpreter_path : caminho para o intérprete Python.
sys_path : Lista de caminhos de Python do sys.path .
O valor de retorno deve ser a lista modificada de caminhos Python.
Veja o próprio .ycm_extra_conf.py do YCMD.
O módulo extra global deve expor as mesmas funções do módulo .ycm_extra_conf.py com as seguintes adições:
YcmCorePreLoad()Opcional.
Este método, se definido, é chamado pelo servidor antes de importar o plug -in C ++ Python. Geralmente não é necessário e seu uso é apenas para usuários avançados.
Shutdown()Opcional.
Chamado antes do servidor saindo de maneira limpa. Geralmente não é necessário e seu uso é apenas para usuários avançados.
A interface HTTP+JSON do YCMD segue Semver. Embora o YCMD tenha visto um uso extensivo nos últimos anos como parte do YCM, o número da versão está abaixo de 1,0, porque algumas partes da API podem mudar um pouco à medida que as pessoas descobrem possíveis problemas que integrem YCMD com outros editores. Em outras palavras, a API atual pode, sem querer, ser específica do VIM. Não queremos isso.
Observe que as APIs internas da YCMD (ou seja, qualquer outra coisa senão HTTP+JSON) não são cobertas por Semver e mudarão aleatoriamente por baixo de você. Não interaja com o código Python/C ++/etc diretamente!
Sem a autenticação do HMAC, é possível que um site malicioso se veste o usuário. Não se esqueça que o Evil.com pode enviar solicitações a servidores que ouvem no host local se o usuário visitar o Evil.com em um navegador.
Isso não é apenas uma preocupação teórica ; Uma exploração de execução de código remoto de prova de comprovação de trabalho foi criado para YCMD em execução no localhost. A autenticação HMAC foi adicionada para bloquear esse vetor de ataque.
Observe que este projeto é lançado com um código de conduta colaborador. Ao participar deste projeto, você concorda em cumprir seus termos.
Se você tiver dúvidas sobre o plug-in ou precisar de ajuda, use a lista de discussão YCMD-Users.
A página inicial do autor é http://val.markovic.io.
Este software está licenciado sob a licença GPL V3. © 2015-2019 colaboradores da YCMD