Ace Editor 擴充套件編寫初步(轉)

發表於2019-05-11

讓 GitHub 識別定製的語言
GitHub 的語法高亮是通過 github/linguist 實現的, 實際上封裝了 Pygments,
如果要讓 GitHub 能對程式碼進行高亮, 就需要 Pygments 先支援這們語言,
然後, 在上述 repo 的 lib/linguist/languages.yml 檔案裡宣告語言怎樣識別,
一般是根據檔案字尾進行區分, 有時也會進行更復雜的處理判斷具體語言,
在 GitHub 宣告語言的步驟並不難, 幾行宣告即可, 外加一些示例的檔案
https://github.com/github/linguist/pull/906/files
langauges.yaml 裡主要是這樣一些選項:
https://github.com/github/linguist/blob/master/lib/linguist/languages.yml#L6
type - data, programming, markup, or nil lexer -  lexer String (預設是語言名稱) aliases - aliases (implicitly includes name.downcase) ace_mode - A String name of Ace Mode (if available) wrap - Boolean wrap to enable line wrapping (default: false) extensions - 相關的字尾名 interpreter - An Array of associated interpreters primary_extension - 唯一的語言字尾名 searchable - Boolean flag to enable searching (defaults to true) color - 10 進位制的顏色.
Pygments 告一段落了, 現在是 Ace 的問題, 需要編寫對應的外掛
文件
Ace 的文件一個是在官網比較詳細: http://ace.c9.io/
此外在 GitHub Wiki 上還有一些: https://github.com/ajaxorg/ace/wiki/_pages
相對來說原始碼提供的幫助也非常大, 已有的例子比較清晰,
外掛開發流程
新增外掛大致是要修改下面幾個地方,
新增語言到 modelist
lib/ace/ext/modelist.js 裡需要按格式填入 Cirru 對應的字尾,
在 kitchen-sink/ 頁面進行除錯時會用到 modelist 的內容.
新增示例的程式碼
我新增的程式碼是在 demo/kitchen-sink/docs/cirru.cirru
kitchen-sink/ 裡除錯時會用到這邊的程式碼, 通過請求載入到編輯器裡,
make build 執行時似乎也會引入這部分程式碼...
mode 檔案
主要的語言配置檔案在 ace/lib/ace/mode/ 下, 比如 cirru.js 控制 Cirru 的行為
主要的配置有 Folding, Indent, 通過覆寫一些方法對具體邏輯進行調整,
另外語法高亮也從這個檔案引入, 如果是沿用已有的模版, 要注意修改相關變數名.
再有一個是 Worker 可能涉及到, 是通過 Web Worker 在後臺處理語法的,
在編寫 Cirru 外掛時, 遇到後臺跑的 JSON Worker 沒有刪除, 會給我報錯.
我不清楚具體功能, Cirru 裡用不到, 臨時去掉了程式碼. 文件倒是有:
https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode#extending-the-mode
https://github.com/ajaxorg/ace/wiki/Syntax-validation
Indent 是 Cirru 裡沒做的, 相關程式碼也去掉了.
Folding 實現略複雜, 不過, Ace 提供了機制可以使用已有的其他 Style,
比如 JSON 整合了 CStyle 的 Folding, Cirru 於是繼承了 CoffeeStyle.
$rules 檔案
cirru_highlight_rules.js 是這樣一個檔案專門高亮語法.
檔案也放在 ace/lib/ace/mode/. 平級有時可能還有其他的檔案...
關於高亮如何生成, 看一些 JSON 的例子會覺得比較清晰:
https://github.com/ajaxorg/ace/blob/master/lib/ace/mode/json_highlight_rules.js#L41
文件上例子講得也比較清晰, 主要就是一些狀態, 預設是 start:
http://ace.c9.io/#nav=higlighter
this.$rules = { "start" : [ {
        token : "text",
        merge : true,
        regex : "<\\!\\[CDATA\\[",
        next : "cdata" }, "cdata" : [ {
        token : "text",
        regex : "\\]\\]>",
        next : "start" }, {
        token : "text",
        merge : true,
        regex : "\\s+" }, {
        token : "text",
        merge : true,
        regex : ".+" } ]
};
每次匹配, 都會都陣列裡選取一條, 按 regex 進行匹配,
next 表示匹配當前項之後, 轉到新的一個 state 去, 如此迴圈.
文件裡沒寫, 但是原始碼裡暗示 Ace 有 Pygments 類似的 push 和 pop,
https://github.com/ajaxorg/ace/blob/master/lib/ace/mode/haskell_highlight_rules.js#L59
Ace 的 Token 是和 TextMate 保持一致的, 具體可看文件:
https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode#common-tokens
因此考慮在 Theme 方面兩者也有一些共通,, 還有 Sublime 也是..
具體可以看我 PR 上提交的修改. 也可能存在一些需要糾正的地方:
https://github.com/ajaxorg/ace/pull/1780
除錯
關於 $rules 的除錯在 Creator 裡做基本可以完成了
http://ace.c9.io/tool/mode_creator.html
完了手動複製到檔案裡去, 注意一些變數名可能要更改到對應 Cirru
ace/kitchen-sink.html 可以直接載入檔案執行, 簡單的 Nginx 靜態伺服器即可,
當然這個是在幾個應對的檔案修改完成以後..
build
暫時沒去研究 build 用途.. 主要是對檔案進行和合並的樣子:
npm install make build
合併後, index.html 可以開啟直接執行, build/ace/kitchen-sink.html 也是
在 kitchen-sink.html 裡開啟的話, 就是下面這個樣子:

原文:http://blog.segmentfault.com/jiyinyiyong/1190000000397100
評論(0)

相關文章