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贡献者