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

相關文章
相關標籤/搜索