github atom建立本身的语法高亮

  使用atom一段时间了,有些插件还不是很成熟。好比项目中使用protobuf,早就有人写了语法高亮(https://github.com/podgib/atom-protobuf),可是效果不是很好。因而决定本身写一个。html

  atom linux的配置目录在~/.atom下,里面有一个packages目录,全部安装的插件(或者叫作包)都在这里。全部在这里的包在启动时都会自动加载。所以,咱们直接在这里建立一个包。java

cd .atom/packages
mkdir language-protobuf
cd language-protobuf

atom的packages都是有特定的目录结构和文件的。首先,要有一个package.json来描述你的包,在language-protobuf目录下建立它。node

{
  "name": "language-proto",
  "version": "0.2.0",
  "description": "Syntax highlighting for google protobuf",
  "repository": "https://github.com/changnet/language-protobuf",
  "license": "MIT",
  "engines": {
    "atom": "*",
    "node": "*"
  }
}

其中,name(包名)、version(版本)、description(描述)这些都是要的。若是你准备发布这个包repository(源)这些也是要的。能够到github上参考别人的怎么写。linux

  如今已经建立了一个空包。要实现语法高亮,就要有一些语法规则来指定如何高亮。下面开始建立语法规则。git

mkdir grammars
cd grammars

而后在grammars目录下建立语法规则文件protobuf.cson(atom的配置文件用cson来保存的)github

'scopeName': 'source.protobuf'
'name': 'protobuf'
'fileTypes': ['proto']
'patterns': [
  {
    'match': '\\b[0-9]+\\b'
    'name': 'constant.numeric.protobuf'
  }
]

上面是一个简单的语法规则文件。web

scopeName是指定本文件的范围,至关于C++中的namespace。好比你写了一个C的语法高亮(source.c),而后要写一个C++的语法高亮,那么能够直接在C++的语法文件中'include': 'source.c'便可把C的语法规则给包含进来。
正则表达式

name是语法的名字,C就是C,java就是java。atom一般会把它显示在状态栏右下角。json

fileTypes是文件后缀。atom打开时会根据文件后缀来判断采用哪种语法高亮。多个文件后缀按行分开便可。如sublime-text

'fileTypes': [
'h'
'hpp'
'cpp'
]

patterns是规则匹配的集合,它是一个数组,每一个元素是一个对象{}。

在上面的例子中,对象的内容以下:

match是正则表达式(在cson中转义字符要多加一个\,如\b变成\\b),指明如何要匹配到高亮的目标。如\\b[0-9]+\\b用来匹配常数。好比"required int32 id = 1;"中的1

name是高亮的名字,constant.numeric.protobuf表示用constant(常量)下的numeric(数字)规则(什么字体、颜色)来高亮匹配的字符。

  一个简单的包就解释完了。可是constant.numeric.protobuf是如何指定高亮规则的。这得从atom的主题提及。atom的主题分为ui和语法。ui是界面(像标签、状态栏...)相关的,与语法无关。语法主题则是控制代码高亮的,在设置中指定。我使用的是Monokai主题,分析这个主题能够发现它里面有一个index.less文件(https://github.com/burntime/atom-monokai/blob/master/index.less)。里面指定了大部分结构的高亮规则。好比:

.comment {
  color: #75715E;
}

.string {
  color: #E6DB74;
}

.constant.numeric {
  color: #AE81FF;
}

这分别指定了comment(注释)、string(字符串)、constant.number(常量分类下的数字)的颜色。而在constant.numeric.protobuf这个命名中,从上而下找。先找到constant,再到numberic,发现protobuf没找到,因而就使用constant.numeric的颜色。因此,若是你要先了解主题中有哪些颜色分类能够用。

  前因后果了解了,下面咱们来添加更多的规则。

  {
    'match': '\\b(message|enum|service)\\b'
    'name': 'storage.type.custom.protobuf'
  }
  {
    'match': '\\b(rpc|returns)\\b'
    'name': 'keyword.protobuf'
  }
  {
    'match': '\\b[0-9]+\\b'
    'name': 'constant.numeric.protobuf'
  }
  {
    'match': '\\b(required|optional|repeated)\\b'
    'name': 'storage.modifier.protobuf'
  }
  {
    'captures':
      '1':
        'name': 'storage.modifier.protobuf'
      '2':
        'name': 'entity.name.instance.protobuf'
    'match': '\\b(required|optional|repeated)(\\s+\\w+)\\b'
    'name': 'entity.name.instance.protobuf'
  }

仔细看上面最后一条规则,与其余不同。

captures表示要匹配的多个规则。第一个是storage.modifier.protobuf,另外一个是entity.name.instance.protobuf。可是只有一个正则表达式啊,如何匹配多个呢?仔细看正则表达式,你会发现有两个括号。(required|optional|repeated)匹配第一个,(\\s+\\w+)匹配第二个。这样,"required Info info = 1;"中的required按第一个规则高亮,Info按第二个规则高亮。而它自己的名字entity.name.instance.protobuf则不指定语法高亮了,随意写均可以。(PS:这个规则是我推导测试出来的,未找到官方文档的说明)

  接着继承添加其余规则:

  {
    'begin': '"'
    'beginCaptures':
      '0':
        'name': 'punctuation.definition.string.begin.protobuf'
    'end': '"'
    'endCaptures':
      '0':
        'name': 'punctuation.definition.string.end.protobuf'
    'name': 'string.quoted.double.protobuf'
    'patterns': [
      {
        'include': 'punctuation.definition.string.begin.protobuf'
      }
      {
        'include': 'punctuation.definition.string.end.protobuf'
      }
      {
        'match': '\\\\.'
        'name': 'constant.character.escape.protobuf'
      }
    ]
  }

这是一个很复杂的规则,连我看得也不是很明白。这是一个匹配字符串的规则。begin表示字符串以"开始,beginCaptures表示开始字符串要匹配多个规则(万一这个开始字符串很复杂),其中的name也表示高亮规则。end表示字符串以"结束,endCaptures对应。string.quoted...表示以字符串规则进行高亮,注意,若是这个整个规则中某个部分(好比开始部分的名字)未找到对应高亮规则,则使用这个规则。patterns表示字符串中包含多个匹配规则,还要在字符串内部进一行匹配。好比'\\\\.'表示正则匹配一个\和一个\r\n之外的字符(即正则中的点号),即匹配字符串中\t之类的。include表示字符串内部包含其余现成高亮规则,遗憾的是我并无测试成功。只有写完整的match才OK。

  一此为止,全部的匹配规则都已介绍完了。若是还有你想高亮而不能高亮的地方,哪就在正则表达式上多下点功夫。另外一个好办法是去看一下其余如今的语言的高亮是怎么作的。

  写完了,固然还要调试。下面说几个调试要点:

语法文件是在打开atom的时候加载的,你改了后,要看看效果。一种办法是重启atom;另外一种办法是ctrl+shift+p,输入widown:Reload从新加载,对应快捷键是ctrl+alt+r

把鼠标放在高亮的字符尾,而后ctrl+shift+p,输入Editor:log curso scope,atom会在右上角显示当前的高亮信息。

atom自己是基于webkit内核的一个web编辑器。在View-->devloper-->toggle developer tools便可打开web调试界面。对应作web的来讲,这个应该很容易。

  调试完了,该说一下发布。atom是github开发的,它的包要在github上(也可能不须要,但我发布时确实要用到github的密码)。所以当前开始的包要在github上建立一个源,测试好,把最新的代码提交。而后从cmd进入到包的根目录,利用atom自带的apm进行发布。

apm publish minor

第一次的时候,要注册atom开发账号(能够直接用github账号关联),而后拿到账号中的开发key进行绑定

而后从新发布:

若是没有什么问题,发布成功后就能够在atom的设置界面搜索并进行安装。

proto的语法高亮最终效果以下:

在atom中搜索language-proto能够搜索到这个包。

参考:

http://blog.gaku.net/create-a-custom-syntax-highlighting-with-atom-editor/

http://stackoverflow.com/questions/23963733/syntax-highlighting-guide-for-atom

http://sublime-text-unofficial-documentation.readthedocs.org/en/latest/reference/syntaxdefs.html

相关文章
相关标签/搜索