github atom創建自己的語法高亮


  使用atom一段時間了,有些插件還不是很成熟。比如項目中使用protobuf,早就有人寫了語法高亮(https://github.com/podgib/atom-protobuf),但是效果不是很好。於是決定自己寫一個。

  atom linux的配置目錄在~/.atom下,里面有一個packages目錄,所有安裝的插件(或者叫做包)都在這里。所有在這里的包在啟動時都會自動加載。因此,我們直接在這里創建一個包。

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

atom的packages都是有特定的目錄結構和文件的。首先,要有一個package.json來描述你的包,在language-protobuf目錄下創建它。

{
  "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上參考別人的怎么寫。

  現在已經創建了一個空包。要實現語法高亮,就要有一些語法規則來指定如何高亮。下面開始創建語法規則。

mkdir grammars
cd grammars

然后在grammars目錄下創建語法規則文件protobuf.cson(atom的配置文件用cson來保存的)

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

上面是一個簡單的語法規則文件。

scopeName是指定本文件的范圍,相當於C++中的namespace。比如你寫了一個C的語法高亮(source.c),然后要寫一個C++的語法高亮,那么可以直接在C++的語法文件中'include': 'source.c'即可把C的語法規則給包含進來。

name是語法的名字,C就是C,java就是java。atom通常會把它顯示在狀態欄右下角。

fileTypes是文件后綴。atom打開時會根據文件后綴來判斷采用哪一種語法高亮。多個文件后綴按行分開即可。如

'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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM