Language agnostic 表示自动完成场景的语言标记的最佳方法

Language agnostic 表示自动完成场景的语言标记的最佳方法,language-agnostic,autocomplete,token,Language Agnostic,Autocomplete,Token,正如你们中的一些人所知,我正在开发自己的IDE。你可能会想“哦,不,另一个?!”-别担心,没有人强迫你使用它,我怀疑它是否会被认真出版 那么,继续讨论主要问题。我正在尝试实现一个自动完成系统。确切的用户界面并不重要但是,以灵活的方式存储语言/库标记是我的主要问题。 假设我们建议用户使用CSS选择器或属性。我们会有类似于: - css/core - a // anchor tag - etc // all va

正如你们中的一些人所知,我正在开发自己的IDE。你可能会想“哦,不,另一个?!”-别担心,没有人强迫你使用它,我怀疑它是否会被认真出版

那么,继续讨论主要问题。我正在尝试实现一个自动完成系统。确切的用户界面并不重要但是,以灵活的方式存储语言/库标记是我的主要问题。

假设我们建议用户使用CSS选择器或属性。我们会有类似于:

- css/core
  - a                      // anchor tag
  - etc                    // all valid html tags
  - .stuff                 // class name parsed from user project
  - ?etc                   // more stuff parsed from user project (ids, classes...)
- css/properties
  - border                 // regular css properties - we also need to associate
                           // <border-style> and <color> value tokens
  - etc                    // the rest of them
- css/values/border-style  // property value tokens
  - solid
  - dotted
- css/values/color
  - red
  - green
  - fucshia
-css/core
-锚定标签
-etc//所有有效的html标记
-.stuff//从用户项目解析的类名
-?etc//从用户项目解析的更多内容(ID、类…)
-css/属性
-边框//常规css属性-我们还需要关联
//和价值代币
-等等//
-css/值/边框样式//属性值标记
-坚实的
-点缀
-css/值/颜色
-红色的
-绿色的
-岩藻
所以每个令牌都有一个名称空间,这样我们就可以在令牌之间进行跟踪。与BNF类似,一些标记值由子标记组成,例如边框和颜色的大小写

1.不要忘记,我们需要存储任何可能与具有奇异语法的语言相关的内容2。另外,需要注意的是,我需要以某种方式将上述信息与上下文相关的信息合并,例如从项目文件中收集的类名列表。这应该是快速有效的,不会导致任何重复的令牌等

所以,总而言之,这里的事情非常复杂,我真的想不出一个通用灵活的解决方案。请记住,IDE应该适合任何类型的语言,这使得它更加复杂


例如,我不确定这个问题是否更适合,所以我将把它留给mods来决定。

经过各种人的仔细思考和建议,数据库是存储自动完成信息的唯一逻辑解决方案

在这个练习中,我编写了几个脚本,解析代码/规范以生成自动完成代码

例如,在这里我意识到PHP至少有8000多个函数(=>自动完成项)

因此,将这些信息存储在PHP文件中并在IDE启动时加载是不好的。相反,我的数据库将存储这些信息


任何特定于项目的自动完成都将存储在单独的数据库表中,这有助于避免阻塞主文档表。

在我以前的工作中,我们在糟糕的网站上销售制造品(我是一名工程师,所以我发誓这不是我的错)。有一天,上级决定在我们所有的产品上加一个“推荐商品”框

这方面的常识方法是在每个产品和所有其他产品之间建立一种非常酷和有趣的关系,然后向客户提供有关实际相关产品的相关、最新信息。不幸的是,在我的工作中,没有人知道如何让我们预先构建的网站做到这一点

相反,他们将五个产品ID的数组附加到每个产品上。这些产品ID是基于经验丰富的销售人员和常识的推荐而硬编码的,没有花哨的算法


这个故事的寓意是,您可能希望关注这样一个事实,即IDE的最终用户只会看到大约10个RecComEndation,因此您可能应该想出一些规则,以实现“相当好”的结果十大潜在变量列表:获取一些基本语法规则,然后根据代码中的相似性、每个变量的频率等进行预测。然后你可以把它放到床上,专注于IDE中更重要的部分

一般来说,困难的部分是收集要提供的令牌,并将它们与正确的键入上下文相匹配。(输入部分键入的行的哪个字符要用什么激活,以及输入语言类型系统。)相比之下,表示和查询选项列表很容易,也不重要;一个天真的方法是很好的

现有IDE所做的一件事是,它们定期将您的代码编译到后台线程中,使用编译器的特殊版本或模式生成程序中存在的函数/变量/等的列表。该列表交替称为“标记文件”、“浏览信息”或“程序数据库”。它存储项目中每个函数的名称、路径、类型,有时还存储一些自动提取的文档;为了提高性能,它需要以增量方式工作,也就是说,避免重新编译没有更改的内容,至少在单个文件的粒度上是这样。它还需要比真正的编译器更能容忍错误,因为它对部分类型的代码进行操作

然后,当您键入时,编译器知道自动完成程序应该出现的某些上下文:在您键入函数的“.”之后,在您键入CSS属性名称的一部分时,等等。这些取决于模式匹配部分键入的代码。这些没有统一的原则;这只是一些特殊情况,不同语言的情况不同。例如,当您在“case SomeEnum.Foo:”中键入空格时,一些IDE将找到封闭的switch语句,推断其类型,找到该枚举类型的定义,并将其值作为选项提供

这一切的实际后果是,你永远无法得到自动补全器所能提供的东西的统一表示;取而代之的是,您混合了特定于语言的上下文识别技巧、各种上下文的列表等
getAutocompletionList(editor) {
  plugin = editor.languagePlugin;
  plugin.getAutocompletionList(editor.cursorPosition, editor.parsedDocument);
}
h1 {
    text-align: <cursor>
[cssTopLevelContext] {
    [cssPropertyContext]: [cssPropertyValueContext]
}
// CSSLanguageBinding
getAutocompletionList(cursorPosition, document) {
    completionContext = this.getCompletionContext(cursorPosition, document);
    // completionContext is { 
    //     'name': 'cssPropertyValueContext', 
    //     'propertyName': 'text-align' 
    // }
    return this.completionDatabase.getCompletionList(completionContext);
    // returns ['left', 'center', 'right'];
}