YCMD是一台服務器,可為代碼完成和其他代碼透明用例(例如語義goto命令(等))提供API。對於某些Filetypes,YCMD還可以提供診斷錯誤和警告。
YCMD最初是YouCompleteme代碼庫的一部分,但已分為一個單獨的項目,因此可以在VIM以外的其他編輯中使用。
如果要實現客戶端,請檢查API文檔。通過閱讀(並運行) example_client.py文件來學習如何與YCMD進行交互的好方法。有關示例文件夾,請參見Readme,以獲取有關如何運行示例客戶端的詳細信息。
如果您構建了一個,請隨時發送拉動請求,並在此處添加鏈接。
如果您想開發YCMD,請查看運行測試的說明。
這全都適用於Ubuntu Linux。有關在其他操作系統上運行YCMD的詳細信息可以在YCM的說明中找到(忽略特定於VIM的零件)。請注意, YCMD在Python 3.8.0+上運行。
首先,安裝最小依賴性:
sudo apt install build-essential cmake python3-dev
接下來,安裝您需要的特定語言依賴項:
sudo apt install golang-go進行。sudo apt install npm用於JavaScript和打字稿。sudo apt install mono-devel c#。sudo apt install openjdk-8-jre for java。當您第一次克隆存儲庫時,您需要更新子模型:
git submodule update --init --recursive
然後運行python3 build.py --all或任何由python3 build.py --help 。這應該讓你前進。
有關構建YCMD的更詳細說明,請參見YCM的說明(忽略特定於VIM的零件)。
n結尾。x-ycm-hmac HTTP標頭中包括HMAC。 HMAC是從啟動和請求/響應主體傳遞給服務器的共享秘密計算的。消化算法是SHA-256。該服務器還將在其響應中包括HMAC;您必須在使用響應之前對其進行驗證。請參閱example_client.py查看如何完成。YCMD中有幾個完成引擎。最基本的是一個基於標識符的完成者,該完成器收集完成請求中提供的文件中的所有標識符,以前提供的其他文件類型的其他文件以及CTAG產生的任何標籤文件。該引擎是非語義的。
YCM也有幾個語義引擎。有基於Clangd的完成者,都為C家族語言提供語義完成。還有一個基於絕地武士的完成者Python的語義完成,Python是一個基於OmnishArp的C#的完成者,C#是GO的基於GOPLS的完成者(使用GOPLS來跳至定義),這是一個基於TSSERVER的JavaScript和Typescript的基於TSSERVER的完成者,用於JDT.LS的JAVT.LS基於jdt.ls的服務器,用於Java的Java和Rls ruders and ruderers and ruderers。隨著時間的流逝,會添加更多。
還有其他完成引擎,例如Filepath Postemer(標識符完成者的一部分)。
服務器將自動檢測到哪種完成引擎在任何情況下都是最好的。有時,它一次查詢其中幾個,將輸出合併並呈現結果。
語義引擎僅在代碼中插入語義“觸發器”後才觸發。如果收到的請求表明用戶的光標是在string foo; foo.在C#文件中,這將觸發語義引擎來檢查foo的成員,因為.是C#的默認語義觸發器(觸發器可以動態更改)。如果文本是string foo; foo.zoo ,語義完成仍然會觸發(觸發器是用戶輸入的zoo單詞後面的),並且結果將通過zoo查詢過濾。
語義完成也可以通過設置force_semantic: true ,但是只有在用戶用鍵盤快捷鍵的用戶明確要求的語義完成時,您才應該這樣做;否則,請將其保留到YCMD,以決定何時使用哪種引擎。
語義完成並不總是使用的原因,即使在可用的情況下也是因為語義引擎可能會很慢,而且由於大多數情況下,用戶實際上並不需要語義完成。
有兩個主要用例用於代碼完成:
第一種用例是最常見的用例,並且用標識符完成引擎(順便說一句快速燃燒)對其進行了微不足道的解決。第二個需要語義完成。
要注意的關鍵是,完成過濾不是基於輸入是完成的字符串前綴(但也有效)。輸入需要是完成的子序列。這是一種奇特的方式,即以填寫字符串以出現在輸入中的順序中,都需要以任何輸入字符存在。因此, abc是xaybgc的子序列,但不是xbyxaxxc的子序列。
子序列過濾器刪除了與輸入不匹配的任何完成,但隨後分類系統啟動了。這有點涉及,但是大致說明“ Word Boundare”(WB)子序列字符匹配比非WB匹配更“價值”。實際上,這意味著給出“ gua”的輸入,完成的“ getuseraccount”在列表中的排名將高於“ fooguxa”的完成(這兩個都是子序列匹配)。單詞邊界字符都是所有的資本字符,在完成字符串中的下劃線和第一個字母字符之前。
如果服務器已經有一段時間沒有收到任何請求(由--idle_suicide_seconds ycmd flag控制),則它將自動關閉。這對於啟動YCMD死亡而不告訴YCMD的過程或YCMD懸掛的過程(這應該非常罕見)的情況很有用。
如果您正在為YCMD實施客戶端,請確保您有某種定期pings ycmd的靜靠背景線程(只需致電/healthy處理程序,儘管任何處理程序都可以使用)。
您也可以通過傳遞--idle_suicide_seconds=0將其關閉,儘管不建議這樣做。
在啟動期間,YCMD嘗試加載ycm_core庫,並以以下返回代碼之一退出,如果不成功:
ycm_core庫;ycm_core庫的版本已過時。您可以在服務器啟動時為YCMD提供設置。您可以調整一個default_settings.json文件。有關每個選項的說明,請參見YCM用戶指南中的選項部分。將路徑傳遞到修改後的設置文件以--options_file=/path/to/file標誌為YCMD。請注意,您必須設置hmac_secret設置(用base64編碼值)。因為您通過的文件包含一個秘密令牌,請確保您以安全的方式創建臨時文件( mkstemp() Linux System Call是一個好主意;對其他OS使用類似的內容)。
啟動後,YCMD將刪除您在讀取它後提供的設置文件。
設置文件是您的編輯器應根據用戶配置的值製作的。還有一個額外的文件( .ycm_extra_conf.py )您的用戶應該提供以配置某些語義完成器。有關它的更多信息也可以在YCM用戶指南的相應部分中找到。
.ycm_extra_conf.py規範.ycm_extra_conf.py模塊可以定義以下功能:
Settings( **kwargs )此功能允許用戶按每個項目或全球配置語言完成者。目前,基於Libclang的完成者需要其他完成者的可選。可以從kwargs詞典中檢索以下論點,並且對於所有完成者來說都是共同的:
language :稱為該功能的完成者的標識符。它的價值是Python完成者的python和cfamily的C Family。該參數可一次配置多個完成者。例如:
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 :當前編輯的文件的絕對路徑。
client_data :客戶端應用程序提供的任何其他數據。有關示例,請參見YouCompleteme文檔。
返回值是一個詞典,其內容取決於完成者。
LSP服務器通常通過初始請求支持用戶配置。這些通常在UI中作為選項呈現。 YCMD通過允許用戶指定服務器初始消息中傳遞的設置的確切詞典來使用.ycm_extra_conf.py支持這一點。這些選項是從ls密鑰下的Settings返回的。 Python詞典將其轉換為JSON,並在LSP初始化請求中列出了逐字化。為了確定服務器的選項集,請諮詢服務器的文檔或package.json文件。 config_sections對像是一個詞典,其鍵是“部分”,值是與這些部分相對應的設置(通常在ls對像中)。這更加指定,需要試用和錯誤才能使其起作用。它是可選的,僅當您明確啟用workspace/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' : {} }此外,YCMD可以使用任何語言服務器,給定文件類型和命令行。用戶選項language_server可用於插入LSP服務器YCMD通常不知道。該值是包含以下字典的列表:
name :表示服務器名稱的字符串cmdline :表示執行服務器的命令行的列表(如果未指定端口,則可選;強制性)port :可選。如果指定,則將TCP連接用於此端口。如果設置為* ,則選擇一個未使用的本地端口,並在cmdline中以${port} (請參見下面的示例)。filetypes :支持的Filetypes列表。project_root_files :告訴ycmd哪個文件表示項目root。capabilities' :覆蓋YCMD的默認LSP功能。workspace/configuration支持,請檢查與LSP服務器相關的額外Conf詳細信息。additional_workspace_dirs :指定應在LSP服務器啟動上打開的靜態知名工作區。triggerCharacters :覆蓋LSP服務器的觸發字符以完成。當服務器令人討厭地請求每個字符(例如Whitespace字符)上要求完成時,這可能很有用。 {
"language_server" : [ {
"name" : " gopls " ,
"cmdline" : [ " /path/to/gopls " , " -rpc.trace " ],
"filetypes" : [ " go " ],
"project_root_files" : [ " go.mod " ],
"triggerCharacters" : [ " . " ]
} ]
}或者,使用TCP連接:
{
"language_server" : [ {
"name" : " godot " ,
"port" : " 6008 " ,
"filetypes" : [ " gdscript " ]
} ]
}或者,要使用未使用的本地端口,請將port設置為* ,並在cmdline中使用${port} :
{
"language_server" : [ {
"name" : " someserver " ,
"cmdline" : [ " /path/to/some/server " , " --port " , " ${port} " ],
"port" : " * " ,
"filetypes" : [ " somethign " ],
"project_root_files" : [ " somethingfile " ]
} ]
}當以這種方式插入完整器時, kwargs[ 'language' ]將設置為name鍵的值,即上述示例中的gopls 。
目前,沒有language_server ,USCH AS支持許多LSP完成者:
一個人還可以使用project_directory覆蓋根目錄。
def Settings ( ** kwargs ):
return { 'project_directory' : 'src/' } # The path may be absolute as well.注意:如果將基於LSP的完成者配置為支持“內置”的語言,則它覆蓋了內置支持。
LIBCLANG和基於Clangd的完成者調用Settings功能,以使編譯當前文件時使用編譯器標誌。該文件的絕對路徑可在kwargs字典的filename密鑰下訪問。
兩個完成者預期的回報值是包含以下項目的字典:
flags :( libclang的強制性,clangd的可選)編譯器標誌列表。
include_paths_relative_to_dir :(可選)標誌列表中包含路徑相對的目錄。默認為libclang完成器的YCMD工作目錄和.ycm_extra_conf.py的.ycm_extra_conf.py的目錄。
do_cache :(可選)一個布爾值,指示此文件名稱是否應緩存此呼叫的結果(即標誌列表)。默認為True 。如果不確定,默認值幾乎總是正確的。
基於Libclang的完成者還支持以下項目:
override_filename :(可選)一個字符串,指示文件名解析為所提供的文件名的翻譯單元。此相當高級的功能允許使用“ Unity”式構建或取決於其他文件中其他包含的標題文件的項目。
flags_ready :(可選)布爾值表示應使用標誌。默認為True 。如果不確定,默認值幾乎總是正確的。
一個簡單返回標誌列表的最小示例是:
def Settings ( ** kwargs ):
return {
'flags' : [ '-x' , 'c++' ]
}Format子命令的配置可以用額外的conf for java usperver和typeScript Subserver指定。格式選項可以在下面找到:
這些服務器支持以不同於其餘的方式提供的自定義格式選項。為此, Settings功能可以返回formatter屬性。
格式配置的一個示例是:
def Settings ( ** kwargs ):
return {
'formatting_options' : {
'org.eclipse.jdt.core.formatter.lineSplit' : 30 ,
}
}Settings功能允許用戶指定Python解釋器和完成者使用的sys.path ,以提供完成和代碼理解。沒有其他論點。
完成者預期的回報值是包含以下項目的字典:
interpreter_path :(可選)Python解釋器的路徑。 ~路徑中的環境變量擴展。如果不是絕對的路徑,它將通過PATH進行搜索。
sys_path :(可選)備用到sys.path路徑列表。
用法示例:
def Settings ( ** kwargs ):
return {
'interpreter_path' : '~/project/virtual_env/bin/python' ,
'sys_path' : [ '~/project/third_party/module' ]
}PythonSysPath( **kwargs )可選的Python支持。
此功能允許進一步自定義Python Path sys.path 。它的參數是python完成者的Settings功能返回的可能的項目:
interpreter_path :Python解釋器的路徑。
sys_path : sys.path的Python路徑列表。
返回值應為Python路徑的修改列表。
有關一個示例,請參見YCMD自己的.ycm_extra_conf.py 。
全局額外模塊必須揭示與.ycm_extra_conf.py模塊相同的功能,並具有以下添加:
YcmCorePreLoad()選修的。
在導入C ++ Python插件之前,服務器調用此方法。通常不需要它,並且其使用僅適用於高級用戶。
Shutdown()選修的。
在服務器乾淨退出之前調用。通常不需要它,並且其使用僅適用於高級用戶。
YCMD的HTTP+JSON接口遵循SEMVER。儘管YCMD在過去幾年中作為YCM的一部分進行了廣泛使用,但版本號低於1.0,因為當人們發現與其他編輯集成YCMD的問題時,API的某些部分可能會略有變化。換句話說,當前的API可能無意間是特定於VIM的。我們不想要那個。
請注意,YCMD的內部API(即HTTP+JSON以外的其他任何內容)都沒有涵蓋SEMVER,並且會隨機更改您。不要直接與python/c ++/etc代碼進行交互!
沒有HMAC AUTH,惡意網站可能會模仿用戶。不要忘記,如果用戶在瀏覽器中訪問evil.com,eve.com可以將請求發送給在Localhost上聽的服務器。
這不僅是理論上的關注;為在Localhost上運行的YCMD創建了概念驗證遠程代碼執行利用。添加了HMAC AUTH以阻止此攻擊向量。
請注意,該項目已使用貢獻者的行為準則發布。通過參加該項目,您同意遵守其條款。
如果您對插件有疑問或需要幫助,請使用YCMD-users郵件列表。
作者的主頁是http://val.markovic.io。
該軟件是根據GPL V3許可證獲得許可的。 ©2015-2019 YCMD貢獻者