自分のプログラミング言語を作ったのに, Emacsがシンタックスハイライトをしてくれないので(下図),
寂しいなと思っていたところ, Generic Modeというのがあったので, これを使ってハイライトしてみました.
その時のメモ.
寂しいなと思っていたところ, Generic Modeというのがあったので, これを使ってハイライトしてみました.
その時のメモ.
ほとんど, Schemeを関数型言語風にアレンジした見た目です. $x. xはラムダ抽象を表しています.
ハイライトがないと, 全体的にのっぺりとしていて, シンタックスが読みづらい.
というわけで, Generic Modeを以下のように設定しました.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(require 'generic-x) | |
(defun list-interleave (ls res inserting) | |
(cond | |
((not ls) (reverse res)) | |
((not res) (list-interleave (cdr ls) (cons (car ls) res) inserting)) | |
(t (list-interleave | |
(cdr ls) | |
(cons (car ls) (cons inserting res)) | |
inserting)))) | |
(defvar infinterp-operators | |
(apply 'concat (list-interleave | |
'("\\+" "-" "*" "=" ";" "<" ">") | |
'() "\\|"))) | |
(defvar infinterp-builtins | |
(mapcar (function (lambda (x) `(,x . font-lock-builtin-face))) | |
'("mod" "div" "round" "display" "cons" "car" "cdr" "null" ))) | |
;; 文字列リテラル分の\と正規表現用の\で \\|がorを表す. | |
(define-generic-mode 'infinterp-mode | |
;; 1. comment | |
'("#") | |
;; 2. highlights for keywords | |
'("let" "in" "if" "then" "else") | |
;; 3. highlights for each element | |
`(("\\(define\\)\\|\\(<-\\)\\|\\;" | |
. font-lock-type-face) | |
(,infinterp-operators | |
. font-lock-builtin-face) | |
("\sw" | |
. font-lock-string-face) | |
;; define | |
("^\\s-*define\\s-+\\([A-Za-z0-9_/]+\\)" | |
(1 font-lock-function-name-face)) | |
;; mu operator | |
("mu\\s-+\\([A-Za-z0-9_/]+\\)\\s-*\\." | |
(1 font-lock-function-name-face)) | |
;; lambda operator | |
("\\$\\s-*\\([A-Za-z0-9_/ ]+\\)\\s-*\\." | |
(1 font-lock-function-name-face)) | |
. ,infinterp-builtins) | |
;; 4. file name | |
'("\\.lil$") | |
;; 5. hook function | |
nil | |
;; 6. explanation | |
"infinterp mode") |
define-generic-modeへは, モード名以外に6つのパラメータを渡します.
- 最初の要素はコメントの開始文字列, Lispのセミコロンや, Pythonの#, C++の//など.
- 次の要素はハイライトするキーワードの要素
- そして, 各種キーワードや型, 文字列など, 細かいハイライトの指定.
- ハイライトするトークンの正規表現とそれに対応するfont-lock-faceを指定します.
- "ダブルクオーテーションによる文字列"は, 便利な"\\sw"で一発指定できます.
- 4番目の要素はファイル名(正規表現を用いて拡張子などを指定).
- 今回は".lil"で終わるファイルの時にこのモードを起動するような設定.
- 5番目の要素は, hook functionで, モードの起動時に実行される関数. 不要ならnilでもよい.
- 最後にモードの説明を入れます.
Fig.2 : シンタックスハイライト後 |
Web上の設定サンプルは, logファイルのハイライトの例が多かったのですが, オレオレ言語を作った時にも使えました.