YCMD est un serveur qui fournit des API pour la complétion de code et d'autres cas d'utilisation de la compréhension de code comme les commandes GOTO SEMANTIC (et autres). Pour certains fichiers, YCMD peut également fournir des erreurs et des avertissements de diagnostic.
YCMD faisait à l'origine partie de la base de code de YouCompleMe, mais a été divisé en un projet distinct afin qu'il puisse être utilisé dans des éditeurs autres que VIM.
Consultez la documentation de l'API si vous souhaitez implémenter un client. Une bonne façon d'apprendre à interagir avec YCMD est de lire (et d'exécuter) le fichier example_client.py . Voir le dossier ReadMe pour le dossier Exemples pour plus de détails sur la façon d'exécuter l'exemple du client.
N'hésitez pas à envoyer une demande de traction ajoutant un lien à votre client ici si vous en avez construit un.
Si vous cherchez à développer YCMD, consultez les instructions pour exécuter les tests.
C'est tout pour Ubuntu Linux. Les détails sur le fait que YCMD fonctionnent sur les autres systèmes d'exploitation se trouve dans les instructions de YCM (ignorez les pièces spécifiques à VIM). Notez que YCMD fonctionne sur Python 3.8.0+.
Tout d'abord, installez les dépendances minimales:
sudo apt install build-essential cmake python3-dev
Ensuite, installez les dépendances spécifiques à la langue dont vous avez besoin:
sudo apt install golang-go pour go.sudo apt install npm pour JavaScript et TypeScript.sudo apt install mono-devel pour c #.sudo apt install openjdk-8-jre pour java.Lorsque vous vous clonez pour la première fois, le référentiel, vous devrez mettre à jour les sous-modules:
git submodule update --init --recursive
Ensuite, exécutez python3 build.py --all ou l'un des completeurs spécifiques répertoriés par python3 build.py --help . Cela devrait vous faire avancer.
Pour des instructions plus détaillées sur la construction de YCMD, voir les instructions de YCM (ignorer les pièces spécifiques à VIM).
n .x-ycm-hmac . Le HMAC est calculé à partir du secret partagé transmis au serveur au démarrage et du corps de demande / réponse. L'algorithme de digest est SHA-256. Le serveur comprendra également le HMAC dans ses réponses; Vous devez le vérifier avant d'utiliser la réponse. Voir example_client.py pour voir comment c'est fait.Il existe plusieurs moteurs d'achèvement dans YCMD. Le plus fondamental est un complexe basé sur l'identifiant qui collecte tous les identificateurs du fichier fourni dans la demande d'achèvement, d'autres fichiers du même type de fichier qui ont été fournis précédemment et tous les fichiers de balises produites par CTAGS. Ce moteur est non sémantique.
Il existe également plusieurs moteurs sémantiques en YCM. Il y a un complexe basé sur Clangd qui tous deux assurent l'achèvement sémantique pour les langues c. Il y a aussi un complete basé sur Jedi pour l'achèvement sémantique pour Python, un complexe basé sur Omnisharp pour C #, un complexe basé sur GOPLS pour GO (en utilisant GOPLS pour sauter vers les définitions), un complexe basé sur TSServer pour JavaScript et TypeScript, un serveur basé sur JDT.LS pour Java et un RLS de RLS pour Rust. Plus sera ajouté avec le temps.
Il existe également d'autres moteurs d'achèvement, comme le FilePath Endlever (partie de l'identifiant final).
Le serveur détectera automatiquement quel moteur de complétion serait le meilleur dans toute situation. À l'occasion, il en interroge plusieurs à la fois, fusionne les sorties et présente les résultats.
Les moteurs sémantiques ne sont déclenchés qu'après que les «déclencheurs» sémantiques sont insérés dans le code. Si la demande reçue montre que le curseur de l'utilisateur est après le dernier caractère de string foo; foo. Dans un fichier C #, cela déclencherait le moteur sémantique pour examiner les membres de foo parce que . est un déclencheur sémantique par défaut pour C # (les déclencheurs peuvent être modifiés dynamiquement). Si le texte était string foo; foo.zoo , l'achèvement sémantique serait toujours déclenché (le déclencheur est derrière le mot zoo que l'utilisateur tape) et les résultats seraient filtrés avec la requête zoo .
L'achèvement sémantique peut également être forcé par la définition force_semantic: true dans les données JSON pour la demande d'achèvement, mais vous ne devez le faire que si l'utilisateur a demandé explicitement l'achèvement sémantique avec un raccourci clavier ; Sinon, laissez-le à YCMD pour décider quand utiliser quel moteur.
La raison pour laquelle l'achèvement sémantique n'est pas toujours utilisé même lorsqu'il est disponible parce que les moteurs sémantiques peuvent être lents et parce que la plupart du temps, l'utilisateur n'a pas réellement besoin d'achèvement sémantique.
Il existe deux principales cas d'utilisation pour la complétion de code:
Le premier cas d'utilisation est le plus courant et est trivialement abordé avec le moteur d'achèvement de l'identifiant (que BTW flamboie rapidement). Le second a besoin d'achèvement sémantique.
Une chose critique à noter est que le filtrage d'achèvement n'est pas basé sur l'entrée étant un préfixe de chaîne de l'achèvement (mais cela fonctionne également). L'entrée doit être une correspondance de sous-séquence d'un achèvement. C'est une façon sophistiquée de dire que tous les caractères d'entrée doivent être présents dans une chaîne d'achèvement dans l'ordre dans lequel ils apparaissent dans l'entrée. abc est donc une sous-séquence de xaybgc , mais pas de xbyxaxxc .
Le filtre de la sous-séquence supprime tous les compléments qui ne correspondent pas à l'entrée, mais le système de tri entre en jeu. Il est un peu impliqué, mais à peu près les correspondances de caractéristiques de la sous-séquence "Boundary" WB) (WB) sont plus que des correspondances non-WB. En effet, cela signifie que compte tenu d'une entrée de "GUA", l'achèvement "GetUserAccount" serait classé plus haut dans la liste que l'achèvement "Fooguxa" (qui sont tous deux des matchs de sous-séquence). Un personnage limite de mot est tous des caractères de capital, des caractères précédés d'un soulignement et du premier caractère de lettre dans la chaîne d'achèvement.
Si le serveur n'a reçu aucune demande pendant un certain temps (contrôlé par le drapeau --idle_suicide_seconds ycmd), il s'arrête. Ceci est utile pour les cas où le processus qui a commencé YCMD décède sans dire à YCMD de mourir aussi ou si YCMD est suspendu (cela devrait être extrêmement rare).
Si vous implémentez un client pour YCMD, assurez-vous que vous avez une sorte de thread de fond de garde qui pings périodiquement YCMD (appelez simplement le gestionnaire /healthy , bien que tout gestionnaire fera l'affaire).
Vous pouvez également désactiver cela en passant --idle_suicide_seconds=0 , bien que cela ne soit pas recommandé.
Pendant le démarrage, YCMD tente de charger la bibliothèque ycm_core et quitte avec l'un des codes de retour suivants en cas d'échec:
ycm_core est manquante;ycm_core est obsolète. Vous pouvez fournir des paramètres à YCMD sur le démarrage du serveur. Il y a un fichier default_settings.json que vous pouvez modifier. Voir la section Options du Guide de l'utilisateur de YCM pour une description de ce que fait chaque option. Passez le chemin du fichier de paramètres modifié en YCMD en tant qu'indicateur --options_file=/path/to/file . Notez que vous devez définir le paramètre hmac_secret (codez la valeur avec Base64). Parce que le fichier que vous passez contient un jeton secret, assurez-vous que vous créez le fichier temporaire de manière sécurisée (l'appel système mkstemp() Linux est une bonne idée; utilisez quelque chose de similaire pour les autres systèmes d'exploitation).
Après son démarrage, YCMD supprimera le fichier de paramètres que vous avez fourni après qu'il le lit.
Le fichier de paramètres est quelque chose que votre éditeur devrait produire en fonction des valeurs que votre utilisateur a configurées. Il y a aussi un fichier supplémentaire ( .ycm_extra_conf.py ) Votre utilisateur est censé fournir pour configurer certains complets sémantiques. Plus d'informations à ce sujet peuvent également être trouvées dans la section correspondante du guide de l'utilisateur de YCM.
.ycm_extra_conf.py Spécification Le module .ycm_extra_conf.py peut définir les fonctions suivantes:
Settings( **kwargs ) Cette fonction permet aux utilisateurs de configurer les complets linguistiques par projet ou dans le monde. Actuellement, il est exigé par l'extrémité basé sur LibClang et facultatif pour les autres complets. Les arguments suivants peuvent être récupérés du dictionnaire kwargs et sont communs à tous les compleurs:
language : un identifiant du complexe qui a appelé la fonction. Sa valeur est python pour le complexe Python et cfamily pour la Family Emlever. Cet argument est utile pour configurer plusieurs compleurs à la fois. Par exemple:
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 : chemin absolu du fichier actuellement édité.
client_data : Toute données supplémentaires fournies par l'application client. Voir la documentation YouCompleteMe pour un exemple.
La valeur de retour est un dictionnaire dont le contenu dépend de la complétude.
Les serveurs LSP prennent souvent en charge la configuration de l'utilisateur via la demande initialisée. Ceux-ci sont généralement présentés comme des options dans l'interface utilisateur. YCMD prend en charge cela à l'aide du .ycm_extra_conf.py en permettant à l'utilisateur de spécifier le dictionnaire exact des paramètres qui sont passés dans le message Initialise du serveur. Ces options sont renvoyées à partir Settings sous la touche ls . Le dictionnaire Python est converti en JSON et inclus textuellement dans la demande d'initialisation LSP. Afin de déterminer l'ensemble d'options pour un serveur, consultez la documentation du serveur ou le fichier package.json . Un objet config_sections est un dictionnaire dont les clés sont des «sections» et les valeurs sont des éléments de paramètres (généralement trouvés dans l'objet ls ) correspondant à ces sections. Ceci est encore plus sous-spécifié et nécessite des essais et des erreurs pour le faire fonctionner. Il est facultatif et utile que si vous activez explicitement workspace/configuration .
Exemple de configuration LSP:
def Settings ( ** kwargs ):
if kwargs [ 'language' ] == 'java' :
return { 'ls' : { 'java.rename.enabled' : False },
# `config_sections` is not used for java...
'config_sections' : { 'section0' : {} } De plus, YCMD peut utiliser n'importe quel serveur de langue, compte tenu d'un type de fichier et d'une ligne de commande. Une option utilisateur language_server peut être utilisée pour brancher un serveur LSP YCMD ne le saurait généralement pas. La valeur est une liste des dictionnaires contenant:
name : la chaîne représentant le nom du serveurcmdline : La liste représentant la ligne de commande pour exécuter le serveur (facultatif; obligatoire si le port non spécifié)port : facultatif. Si spécifié, une connexion TCP est utilisée à ce port. Si réglé sur * , un port Locall inutilisé est sélectionné et mis en place dans la cmdline comme ${port} (voir des exemples ci-dessous).filetypes : liste des filetypes pris en charge.project_root_files : indique à YCMD quels fichiers indiquent la racine du projet.capabilities' : remplace les capacités LSP par défaut de YCMD.workspace/configuration , vérifiez les détails de confr supplémentaires, pertinents pour les serveurs LSP.additional_workspace_dirs : Spécifie les espaces de travail statistiquement connus qui doivent être ouverts sur le démarrage du serveur LSP.triggerCharacters : remplacer les caractères de déclenchement du serveur LSP pour l'achèvement. Cela peut être utile lorsque le serveur demande odieusement l'achèvement sur chaque caractère ou par exemple sur les caractères d'espace blanc. {
"language_server" : [ {
"name" : " gopls " ,
"cmdline" : [ " /path/to/gopls " , " -rpc.trace " ],
"filetypes" : [ " go " ],
"project_root_files" : [ " go.mod " ],
"triggerCharacters" : [ " . " ]
} ]
}Ou, pour utiliser une connexion TCP:
{
"language_server" : [ {
"name" : " godot " ,
"port" : " 6008 " ,
"filetypes" : [ " gdscript " ]
} ]
} Ou, pour utiliser un port local inutilisé, réglez port sur * et utilisez ${port} dans la cmdline :
{
"language_server" : [ {
"name" : " someserver " ,
"cmdline" : [ " /path/to/some/server " , " --port " , " ${port} " ],
"port" : " * " ,
"filetypes" : [ " somethign " ],
"project_root_files" : [ " somethingfile " ]
} ]
} Lors de la branche dans un complexe de cette manière, le kwargs[ 'language' ] sera défini sur la valeur de la clé name , c'est-à-dire gopls dans l'exemple ci-dessus.
Un certain nombre de finiteurs LSP sont actuellement pris en charge sans language_server , USCH AS:
On peut également remplacer le répertoire racine, avec project_directory .
def Settings ( ** kwargs ):
return { 'project_directory' : 'src/' } # The path may be absolute as well.Remarque: Si un complexe basé sur LSP est configuré pour une langue prise en charge "intégrée", il remplace la prise en charge intégrée.
La fonction Settings est appelée par les compléteurs basés sur LibClang et Clangd pour que les drapeaux du compilateur utilisent lors de la compilation du fichier actuel. Le chemin absolu de ce fichier est accessible sous la clé filename du dictionnaire kwargs .
La valeur de retour attendue par les deux completeurs est un dictionnaire contenant les éléments suivants:
flags : (obligatoire pour libclang, facultatif pour Clangd) Une liste des drapeaux du compilateur.
include_paths_relative_to_dir : (facultatif) Le répertoire auquel les chemins d'inclusion dans la liste des drapeaux sont relatifs. Le répertoire de travail YCMD par défaut pour le répertoire LibClang EXPLALER ET .ycm_extra_conf.py pour le Clangd EXPLALE.
do_cache : (facultatif) Un booléen indiquant si le résultat de cet appel (c'est-à-dire la liste des drapeaux) doit être mis en cache pour ce nom de fichier. Par défaut est True . S'il n'est pas sûr, la valeur par défaut est presque toujours correcte.
Le complexe basé sur LibClang prend également en charge les éléments suivants:
override_filename : (facultatif) Une chaîne indiquant le nom du fichier à analyser comme unité de traduction pour le nom de fichier fourni. Cette fonctionnalité assez avancée permet des projets qui utilisent une version de style «Unity» ou pour les fichiers d'en-tête qui dépendent d'autres incluses dans d'autres fichiers.
flags_ready : (facultatif) Un booléen indiquant que les drapeaux doivent être utilisés. Par défaut est True . S'il n'est pas sûr, la valeur par défaut est presque toujours correcte.
Un exemple minimal qui renvoie simplement une liste de drapeaux est:
def Settings ( ** kwargs ):
return {
'flags' : [ '-x' , 'c++' ]
} La configuration de la sous-commande Format peut être spécifiée avec un CONF supplémentaire pour le subsserver Java et pour le sous-serveur TypeScript. Les options de format peuvent être trouvées ci-dessous:
Ces serveurs prennent en charge les options de formatage personnalisées à fournir d'une manière différente des autres. À cette fin, la fonction Settings peut renvoyer une propriété formatter .
Un exemple de la configuration du formateur serait:
def Settings ( ** kwargs ):
return {
'formatting_options' : {
'org.eclipse.jdt.core.formatter.lineSplit' : 30 ,
}
} La fonction Settings permet aux utilisateurs de spécifier l'interprète Python et le sys.path utilisé par le complexe pour fournir l'achèvement et la compréhension du code. Aucun argument supplémentaire n'est passé.
La valeur de retour attendue par le complexe est un dictionnaire contenant les éléments suivants:
interpreter_path : chemin (facultatif) vers l'interpréteur Python. ~ et les variables d'environnement dans le chemin sont élargies. Si ce n'est pas un chemin absolu, il sera fouillé à travers le PATH .
sys_path : (Facultatif) Liste des chemins apparentés à sys.path .
Exemple d'utilisation:
def Settings ( ** kwargs ):
return {
'interpreter_path' : '~/project/virtual_env/bin/python' ,
'sys_path' : [ '~/project/third_party/module' ]
}PythonSysPath( **kwargs )Facultatif pour la prise en charge de Python.
Cette fonction permet une personnalisation plus approfondie du chemin Python sys.path . Ses paramètres sont les éléments possibles renvoyés par la fonction Settings pour le complexe Python:
interpreter_path : Chemin vers l'interprète Python.
sys_path : Liste des chemins Python de sys.path .
La valeur de retour doit être la liste modifiée des chemins Python.
Voir le propre .ycm_extra_conf.py pour un exemple.
Le module supplémentaire global doit exposer les mêmes fonctions que le module .ycm_extra_conf.py avec les ajouts suivants:
YcmCorePreLoad()Facultatif.
Cette méthode, si elle est définie, est appelée par le serveur avant d'importer le plugin C ++ Python. Il n'est généralement pas requis et son utilisation est uniquement pour les utilisateurs avancés.
Shutdown()Facultatif.
Appelé avant le serveur qui sort proprement. Il n'est généralement pas requis et son utilisation est uniquement pour les utilisateurs avancés.
L'interface HTTP + JSON de YCMD suit Semver. Alors que YCMD a connu une utilisation approfondie au cours des dernières années dans le cadre de YCM, le numéro de version est inférieur à 1,0 car certaines parties de l'API peuvent changer légèrement car les gens découvrent des problèmes possibles intégrant le YCMD à d'autres éditeurs. En d'autres termes, l'API actuelle pourrait involontairement être spécifique à VIM. Nous ne voulons pas ça.
Notez que les API internes de YCMD (c'est-à-dire autre chose que HTTP + JSON) ne sont pas couvertes par Semver et changent au hasard sous vous. N'interagissez pas directement avec le code Python / C ++ / etc directement!
Sans l'authentification HMAC, il est possible pour un site Web malveillant de se faire passer pour l'utilisateur. N'oubliez pas que Evil.com peut envoyer des demandes aux serveurs écoutant sur localhost si l'utilisateur visite Evil.com dans un navigateur.
Ce n'est pas simplement une préoccupation théorique ; Un exploit d'exécution de code à distance de preuve de concept de travail a été créé pour YCMD en cours d'exécution sur LocalHost. L'Auth HMAC a été ajouté pour bloquer ce vecteur d'attaque.
Veuillez noter que ce projet est publié avec un code de conduite de contributeur. En participant à ce projet, vous acceptez de respecter ses conditions.
Si vous avez des questions sur le plugin ou avez besoin d'aide, veuillez utiliser la liste de diffusion YCMD-Users.
La page d'accueil de l'auteur est http://val.markovic.io.
Ce logiciel est sous licence sous la licence GPL V3. © 2015-2019 Contributeurs YCMD