YCMD ist ein Server, der APIs für die Code-Vervollständigung und andere Anwendungsfälle wie semantische GOTO-Befehle (und andere) zur Verfügung stellt. Bei bestimmten Filetypen kann YCMD auch diagnostische Fehler und Warnungen liefern.
YCMD war ursprünglich Teil der Codebasis von YouCompleteme, wurde jedoch in ein separates Projekt aufgeteilt, damit es in anderen Redakteuren als VIM verwendet werden kann.
Überprüfen Sie die API -Dokumentation, wenn Sie einen Kunden implementieren möchten. Ein guter Weg, um zu lernen, wie man mit YCMD interagiert, ist das Durchlesen (und das Ausführen) der Datei example_client.py . Weitere Informationen zum Ausführen des Beispiel -Clients finden Sie im ReadMe -Ordner für Beispiele.
Senden Sie eine Pull -Anfrage, die hier einen Link zu Ihrem Kunden hinzugefügt hat, wenn Sie eine erstellt haben.
Wenn Sie YCMD entwickeln möchten, finden Sie in den Anweisungen zum Ausführen der Tests.
Dies ist alles für Ubuntu Linux. Details zum Laufen von YCMD unter anderen Betriebssystemen finden Sie in den Anweisungen von YCM (ignorieren Sie die vimspezifischen Teile). Beachten Sie, dass YCMD auf Python 3.8.0+ ausgeführt wird.
Installieren Sie zunächst die minimalen Abhängigkeiten:
sudo apt install build-essential cmake python3-dev
Installieren Sie als Nächstes die von Ihnen benötigten sprachspezifischen Abhängigkeiten:
sudo apt install golang-go für Go.sudo apt install npm für JavaScript und TypeScript.sudo apt install mono-devel für C#.sudo apt install openjdk-8-jre für Java.Wenn Sie das Repository zum ersten Mal klonen, müssen Sie die Submodules aktualisieren:
git submodule update --init --recursive
Rennen Sie dann python3 build.py --all oder eine der von python3 build.py --help aufgeführten Vervollständigern. Das sollte dich zum Laufen bringen.
Ausführlichere Anweisungen zum Erstellen von YCMD finden Sie in den Anweisungen von YCM (ignorieren Sie die vimspezifischen Teile).
n .x-ycm-hmac HTTP-Header enthalten. Der HMAC wird aus dem gemeinsam genutzten Geheimnis berechnet, das beim Start und der Anforderung/Antwortkörper an den Server übergeben wurde. Der Digest-Algorithmus ist SHA-256. Der Server wird auch die HMAC in seine Antworten einbeziehen. Sie müssen es überprüfen, bevor Sie die Antwort verwenden. Siehe example_client.py um zu sehen, wie es fertig ist.In YCMD gibt es mehrere Abschlussmotoren. Das grundlegendste ist ein identifierbasierter Abschluss, der alle Kennungen in der in der Abschlussanforderung bereitgestellten Datei, anderen Dateien desselben Filetyps und der zuvor von CTAGs erstellten Tags-Dateien sammelt. Dieser Motor ist nicht semantisch.
Es gibt auch mehrere semantische Motoren in YCM. Es gibt einen Clangd-basierten Abschluss, der beide semantische Fertigstellung für C-Familiensprachen bieten. Es gibt auch einen Jedi-basierten Abschluss für die semantische Fertigstellung für Python, einen Omnisharp-basierten Abschluss für C#, einen GOPLS-basierten Abschluss für GO (mit GOPLs zum Springen zu Definitionen), einem TSSERVERVER-Basis-Basis für JavaScript und Typencript, einem JDT.LS-basierten Server für Java sowie einem RLS-basierten Russ. Weitere werden mit der Zeit hinzugefügt.
Es gibt auch andere Abschlussmotoren, wie den Filepath -Abschluss (Teil des Kennungsabschlusses).
Der Server erkennt automatisch, welche Fertigstellung Engine in jeder Situation am besten ist. Gelegentlich fragt es mehrere von ihnen auf einmal ab, verschmilzt die Ausgänge und präsentiert die Ergebnisse.
Semantische Motoren werden erst ausgelöst, nachdem semantische "Trigger" in den Code eingefügt wurden. Wenn die empfangene Anfrage zeigt, dass der Cursor des Benutzers nach dem letzten Zeichen in string foo; foo. In einer C# -Datei würde dies die semantische Motor aus auslösen, um Mitglieder von foo zu untersuchen, weil . ist ein Standard -semantischer Auslöser für C# (Trigger können dynamisch verändert werden). Wenn der Text string foo; foo.zoo , semantische Fertigstellung würde weiterhin ausgelöst (der Auslöser steht hinter dem zoo -Wort, den der Benutzer eingreift) und die Ergebnisse würden mit der zoo -Abfrage gefiltert.
Die semantische Fertigstellung kann auch durch Einstellen force_semantic: true in den JSON -Daten für die Abschlussanforderung erzwungen werden. Sie sollten dies jedoch nur tun, wenn der Benutzer explizit semantische Fertigstellung mit einer Tastaturverknüpfung beantragte . Lassen Sie es ansonsten YCMD überlassen, zu entscheiden, wann der Motor verwendet werden soll.
Der Grund, warum die semantische Fertigstellung nicht immer verwendet wird, auch wenn verfügbar ist, liegt darin, dass die semantischen Motoren langsam sein können und der Benutzer die meiste Zeit nicht semantische Fertigstellung benötigt.
Es gibt zwei Hauptanwendungsfälle für die Code-Vervollständigung:
Der erste Anwendungsfall ist der häufigste und wird trivial mit dem Identifikator Completion -Engine (die BTW schnell lodert) angesprochen. Der zweite braucht semantische Fertigstellung.
Eine wichtige Sache zu beachten ist, dass die Abschlussfilterung nicht auf der Eingabe basiert, die ein Zeichenfolgenpräfix der Fertigstellung ist (aber das funktioniert auch). Die Eingabe muss eine Subsequence -Übereinstimmung mit einer Fertigstellung sein. Dies ist eine ausgefallene Art zu sagen, dass alle Eingabebereiche in einer Vervollständigungszeichenfolge in der Reihenfolge vorhanden sein müssen, in der sie in der Eingabe erscheinen. abc ist also eine Untersequenz von xaybgc , jedoch nicht von xbyxaxxc .
Der Subsequence-Filter beseitigt alle Abschlüsse, die nicht mit der Eingabe übereinstimmen, aber dann ist das Sortiersystem eingebunden. Es ist ein bisschen involviert, aber ungefähr "Wortgrenze" (WB) -Untersequenzcharakter-Matches sind "wert" mehr als Non-WB-Übereinstimmungen. Tatsächlich bedeutet dies, dass bei der Eingabe von "Gua" der Abschluss "GetUserAccount" in der Liste höher eingestuft wird als in der Abschluss "fooguxa" (beide sind Subsequence -Übereinstimmungen). Ein Wortgrenzcharakter sind alle Kapitalcharaktere, Zeichen, denen ein Unterstrich und der erste Buchstabencharakter in der Fertigstellungszeichenfolge vorangegangen sind.
Wenn der Server seit einer Weile keine Anforderungen erhalten hat (gesteuert vom ycmd -Flag --idle_suicide_seconds ), wird er selbst geschlossen. Dies ist nützlich für Fälle, in denen der Prozess, der YCMD gestartet hat, ohne YCMD zu sterben, oder wenn YCMD hängt (dies sollte äußerst selten sein).
Wenn Sie einen Kunden für YCMD implementieren, stellen Sie sicher, dass Sie einen Keep-Alive-Hintergrund-Faden haben, der YCMD regelmäßig angeht (rufen Sie einfach den /healthy Handler an, obwohl jeder Handler dies tut).
Sie können dies auch durch Übergeben ausschalten --idle_suicide_seconds=0 , obwohl dies nicht empfohlen wird.
Während des Starts versucht YCMD, die ycm_core -Bibliothek zu laden, und beendet sich mit einer der folgenden Rückgaberückscodes, falls erfolglos:
ycm_core -Bibliothek fehlt;ycm_core -Bibliothek ist veraltet. Sie können Einstellungen für YCMD beim Serverstart bereitstellen. Es gibt eine Datei default_settings.json , die Sie optimieren können. Weitere Informationen finden Sie im Abschnitt Optionen in YCMs Benutzerhandbuch für eine Beschreibung der einzelnen Optionen. Geben Sie den Pfad an die Datei der modifizierten Einstellungen an ycmd als an --options_file=/path/to/file -Flag weiter. Beachten Sie, dass Sie die Einstellung hmac_secret festlegen müssen (codieren Sie den Wert mit Base64). Da die Datei, die Sie übergeben, ein geheimes Token enthält, stellen Sie sicher, dass Sie die temporäre Datei auf sichere Weise erstellen (der mkstemp() -Linux -Systemanruf ist eine gute Idee; Verwenden Sie etwas Ähnliches für andere Betriebssysteme).
Nach dem Start löscht YCMD die Einstellungsdatei, die Sie nach dem Lesen angegeben haben.
In der Einstellungsdatei sollte Ihr Editor basierend auf Werten produzieren, die Ihr Benutzer konfiguriert hat. Es gibt auch eine zusätzliche Datei ( .ycm_extra_conf.py ), die Ihr Benutzer bereitstellen soll, um bestimmte semantische Vervollständiger zu konfigurieren. Weitere Informationen dazu finden Sie auch im entsprechenden Abschnitt des Benutzerhandbuchs von YCM.
.ycm_extra_conf.py Spezifikation Das Modul .ycm_extra_conf.py kann die folgenden Funktionen definieren:
Settings( **kwargs ) Mit dieser Funktion können Benutzer die Sprachvervollständiger pro Projektbasis oder global konfigurieren. Derzeit ist es vom libclang-basierten Completeer und optional für andere Vervollständiger erforderlich. Die folgenden Argumente können aus dem kwargs -Wörterbuch abgeholt werden und sind allen Vervollständigern gemeinsam:
language : Eine Kennung des Abschlusses, der die Funktion nannte. Sein Wert ist python für die Python-Complete und cfamily für die C-Family Complete. Dieses Argument ist nützlich, um mehrere Vervollständiger gleichzeitig zu konfigurieren. Zum Beispiel:
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 : Absoluter Pfad der aktuell bearbeiteten Datei.
client_data : Alle zusätzlichen Daten, die von der Client -Anwendung geliefert werden. Ein Beispiel finden Sie in der Dokumentation von YouCompleteme.
Der Rückgabewert ist ein Wörterbuch, dessen Inhalt vom Abschluss abhängt.
LSP -Server unterstützen häufig die Benutzerkonfiguration über die Initialise -Anforderung. Diese werden normalerweise als Optionen in der Benutzeroberfläche dargestellt. YCMD unterstützt dies mithilfe des .ycm_extra_conf.py Diese Optionen werden von Settings unter dem ls -Schlüssel zurückgegeben. Das Python -Wörterbuch wird in JSON konvertiert und wörtlich in die LSP -Initialisierungsanforderung aufgenommen. Um die Optionen für einen Server festzulegen, wenden Sie sich an die Dokumentation oder package.json -Datei des Servers. Ein Objekt config_sections ist ein Wörterbuch, dessen Schlüssel "Abschnitte" und Werte von Einstellungen (normalerweise im ls -Objekt gefunden) sind, die diesen Abschnitten entsprechen. Dies ist noch unterteilter und erfordert Versuch und Irrtum, damit es funktioniert. Es ist optional und nur nützlich, wenn Sie workspace/configuration explizit aktivieren.
Beispiel für die LSP -Konfiguration:
def Settings ( ** kwargs ):
if kwargs [ 'language' ] == 'java' :
return { 'ls' : { 'java.rename.enabled' : False },
# `config_sections` is not used for java...
'config_sections' : { 'section0' : {} } Darüber hinaus kann YCMD bei einem Dateityp und einer Befehlszeile jeden Sprachserver verwenden. Ein Benutzeroption language_server kann verwendet werden, um einen LSP -Server -YCMD in der Regel nicht bekannt zu machen. Der Wert ist eine Liste von Wörterbüchern mit:
name : Die Zeichenfolge, die den Namen des Servers darstelltcmdline : Die Liste, die die Befehlszeile zur Ausführung des Servers darstellt (optional; optionatorisch, wenn der Port nicht angegeben ist)port : Optional. Wenn angegeben, wird eine TCP -Verbindung zu diesem Port verwendet. Wenn auf * festgelegt wird, wird in der cmdline als ${port} ein ungenutzter Locall -Port ausgewählt und verfügbar gemacht (siehe folgende Beispiele).filetypes : Liste der unterstützten Filetypen.project_root_files : Sagt YCMD, welche Dateien das Projektroot angeben.capabilities' : Überschreibt die Standard -LSP -Funktionen von YCMD.workspace/configuration aktivieren, überprüfen Sie die zusätzlichen Conf -Details, die für LSP -Server relevant sind.additional_workspace_dirs : Gibt statisch bekannte Arbeitsbereiche an, die beim LSP -Server -Start geöffnet werden sollten.triggerCharacters : Überschreiben Sie die Triggerzeichen des LSP -Servers zur Fertigstellung. Dies kann nützlich sein, wenn der Server widerlich die Fertigstellung in jedem Charakter oder beispielsweise auf Whitespace -Zeichen anfordert. {
"language_server" : [ {
"name" : " gopls " ,
"cmdline" : [ " /path/to/gopls " , " -rpc.trace " ],
"filetypes" : [ " go " ],
"project_root_files" : [ " go.mod " ],
"triggerCharacters" : [ " . " ]
} ]
}Oder um eine TCP -Verbindung zu verwenden:
{
"language_server" : [ {
"name" : " godot " ,
"port" : " 6008 " ,
"filetypes" : [ " gdscript " ]
} ]
} Oder um einen nicht verwendeten lokalen Port zu verwenden, stellen Sie port auf * fest und verwenden Sie ${port} in der cmdline :
{
"language_server" : [ {
"name" : " someserver " ,
"cmdline" : [ " /path/to/some/server " , " --port " , " ${port} " ],
"port" : " * " ,
"filetypes" : [ " somethign " ],
"project_root_files" : [ " somethingfile " ]
} ]
} Wenn die kwargs[ 'language' ] auf diese Weise eingestuft wird, werden sie auf den Wert des name festgelegt, dh gopls im obigen Beispiel.
Eine Reihe von LSP -Vervollständigern werden derzeit ohne language_server unterstützt.
Man kann das Stammverzeichnis auch mit project_directory überschreiben.
def Settings ( ** kwargs ):
return { 'project_directory' : 'src/' } # The path may be absolute as well.Hinweis: Wenn ein LSP-basierter Abschluss für eine Sprache konfiguriert ist, die "integriert" unterstützt wird, überschreibt er die integrierte Unterstützung.
Die Settings wird von den Vervollständigern von Libclang und Clangd aufgerufen, um die Compiler-Flags beim Kompilieren der aktuellen Datei zu verwenden. Der absolute Pfad dieser Datei ist unter dem filename des kwargs -Wörterbuchs zugänglich.
Der von beiden Vervollständigern erwartete Rückgabewert ist ein Wörterbuch, das die folgenden Elemente enthält:
flags : (obligatorisch für libclang, optional für clangd) Eine Liste von Compiler -Flags.
include_paths_relative_to_dir : (optional) Das Verzeichnis, in das die Pfade in der Liste der Flags relativ sind. Standardmäßig zum YCMD -Arbeitsverzeichnis für das Verzeichnis von Libclang Complete und .ycm_extra_conf.py Verzeichnis für den Clangd Completeer.
do_cache : (optional) Ein Boolescher Angabe, der angibt, ob das Ergebnis dieses Anrufs (dh die Liste der Flags) für diesen Dateinamen zwischengespeichert werden sollte. Standardmäßig True . Wenn sich nicht sicher ist, ist der Standard fast immer korrekt.
Der libclang ansässige Completeure unterstützt auch die folgenden Elemente:
override_filename : (optional) Eine Zeichenfolge, die den Namen der Datei angibt, die als Übersetzungseinheit für den angegebenen Dateinamen analysiert werden soll. Diese ziemlich fortgeschrittene Funktion ermöglicht Projekte, die einen Build im Stil „Unity“ verwenden, oder für Header-Dateien, die von anderen in anderen Dateien enthalten sind.
flags_ready : (optional) Ein Boolescher angibt, dass die Flags verwendet werden sollten. Standardmäßig True . Wenn sich nicht sicher ist, ist der Standard fast immer korrekt.
Ein minimales Beispiel, das einfach eine Liste von Flags zurückgibt, ist:
def Settings ( ** kwargs ):
return {
'flags' : [ '-x' , 'c++' ]
} Die Konfiguration für Format -Unterbefehl kann mit einem zusätzlichen Conf für den Java -Subserver und für den Typscript -Subserver angegeben werden. Die Formatteroptionen finden Sie unten:
Diese Server unterstützen benutzerdefinierte Formatierungsoptionen, die auf andere Weise geliefert werden können als die anderen. Zu diesem Zweck kann die Settings eine formatter -Eigenschaft zurückgeben.
Ein Beispiel für die Formatierkonfiguration wäre:
def Settings ( ** kwargs ):
return {
'formatting_options' : {
'org.eclipse.jdt.core.formatter.lineSplit' : 30 ,
}
} Mit der Settings können Benutzer den Python -Interpreter und den von dem Complete verwendeten sys.path angeben, um die Fertigstellung und das Codeverständnis bereitzustellen. Es werden keine zusätzlichen Argumente verabschiedet.
Der vom Abschluss erwartete Rückgabewert ist ein Wörterbuch mit den folgenden Elementen:
interpreter_path : (optional) Pfad zum Python -Interpreter. ~ und Umgebungsvariablen im Pfad werden erweitert. Wenn nicht ein absoluter Weg, wird er durch den PATH durchsucht.
sys_path : (optional) Liste der Pfade, die auf sys.path vorbereitet sind.
Verwendungsbeispiel:
def Settings ( ** kwargs ):
return {
'interpreter_path' : '~/project/virtual_env/bin/python' ,
'sys_path' : [ '~/project/third_party/module' ]
}PythonSysPath( **kwargs )Optional für Python -Unterstützung.
Diese Funktion ermöglicht eine weitere Anpassung des Python sys.path . Seine Parameter sind die möglichen Elemente, die von der Settings für den Python -Abschluss zurückgegeben werden:
interpreter_path : Pfad zum Python -Interpreter.
sys_path : Liste der Python -Pfade von sys.path .
Der Rückgabewert sollte die modifizierte Liste der Python -Pfade sein.
Ein Beispiel finden Sie in YCMDs eigene .ycm_extra_conf.py .
Das globale zusätzliche Modul muss die gleichen Funktionen wie das Modul .ycm_extra_conf.py mit den folgenden Ergänzungen freilegen:
YcmCorePreLoad()Optional.
Wenn diese Methode definiert ist, wird vom Server vor dem Importieren des C ++ Python -Plugins aufgerufen. Es ist normalerweise nicht erforderlich und es ist nur für erweiterte Benutzer verwendet.
Shutdown()Optional.
Vor dem Server aufgerufen, der sauber ausgeht. Es ist normalerweise nicht erforderlich und es ist nur für erweiterte Benutzer verwendet.
Die HTTP+JSON -Schnittstelle von YCMD folgt Semver. Während YCMD in den letzten Jahren im Rahmen von YCM in den letzten Jahren ausführlich verwendet wurde, liegt die Versionsnummer unter 1,0, da sich einige Teile der API leicht ändern könnten , da Menschen mögliche Probleme entdecken, die YCMD in andere Herausgeber integrieren. Mit anderen Worten, die aktuelle API könnte ungewollt vimspezifisch sein. Das wollen wir nicht.
Beachten Sie, dass die internen APIs von YCMD (dh etwas anderes als HTTP+JSON) nicht von SEMver abgedeckt sind und sich zufällig unter Ihnen verändern. Interagieren Sie nicht direkt mit dem Code Python/C ++/etc. direkt!
Ohne das HMAC -Auth können eine böswillige Website den Benutzer ausgeben. Vergessen Sie nicht, dass Evil.com Anfragen an Server senden kann, die auf Localhost zuhören, wenn der Benutzer Evil.com in einem Browser besucht.
Dies ist nicht nur ein theoretisches Problem ; Für YCMD, das auf Localhost ausgeführt wurde, wurde ein Arbeitsprofessional-Exploit-Exploit für den Proof-of-Concept-Remote-Code erstellt. Das HMAC -Auth wurde hinzugefügt, um diesen Angriffsvektor zu blockieren.
Bitte beachten Sie, dass dieses Projekt mit einem Verhaltenskodex von Mitwirkenden veröffentlicht wird. Wenn Sie an diesem Projekt teilnehmen, erklären Sie sich damit einverstanden, sich an seine Bedingungen einzuhalten.
Wenn Sie Fragen zum Plugin haben oder Hilfe benötigen, verwenden Sie bitte die Mailingliste der YCMD-Benutzer.
Die Homepage des Autors ist http://val.markovic.io.
Diese Software ist unter der GPL V3 -Lizenz lizenziert. © 2015-2019 YCMD-Mitwirkende