現行 (2) - 基本モード作成 ひな型 -¶
独自の Emacs メジャーモード(major-mode)の作成方法.
特に、どこを変更すればよいのか、を記載.
ひな型 ( 例: MAD-X )¶
1;; ================================================== ;;
2;; === madx mode === ;;
3;; ================================================== ;;
4
5;; ---------------------------------------- ;;
6;; [1] MADX モード定義 ;;
7;; ---------------------------------------- ;;
8(define-derived-mode madx-mode prog-mode "MAD-X"
9 "Major mode for editing MAD-X files with comments"
10 (setq-local indent-tabs-mode nil)
11 (setq-local comment-start "//") ;; comment
12 (setq-local comment-start-skip "//+\\s-*") ;;
13 (setq-local font-lock-defaults ;; font-lock-defaults を case-insensitive 設定
14 '((madx-font-lock-keywords) ;; キーワード群
15 nil t nil nil)) ;; keywords-only, case-fold,syntax-alist,syntax-begin
16 (setq-local indent-line-function 'madx-indent-line)
17 ;; -- highlight functions -- ;;
18 (highlight-comments-override-in-madx)
19 (highlight-at-variables-in-madx)
20 (highlight-numbers-in-madx)
21 (highlight-numbers-inside-strings-in-madx)
22 (highlight-strings-in-madx)
23 (highlight-operators-in-madx)
24 (highlight-keywords-in-madx)
25 )
26
27;; ---------------------------------------- ;;
28;; [2] 演算子記号 定義 ;;
29;; ---------------------------------------- ;;
30(defface madx-operator-face
31 '((t (:foreground "wheat" :weight bold)))
32 "Face for MAD-X operators.")
33
34(defun highlight-operators-in-madx ()
35 "Highlight common operators in MAD-X."
36 (font-lock-add-keywords
37 nil
38 '(("[:=;+\\-*/]" (0 'madx-operator-face prepend)))))
39
40;; ---------------------------------------- ;;
41;; [3] キーワード ハイライト 定義 ;;
42;; ---------------------------------------- ;;
43;; -- [3-1] フォントフェイスの定義 -- ;;
44(defface madx-keyword-face-1
45 '((t (:foreground "orchid" :weight bold)))
46 "Face for MAD-X controls commands.")
47(defface madx-keyword-face-2
48 '((t (:foreground "darkorange" :weight bold)))
49 "Face for MAD-X fundamental commands.")
50(defface madx-keyword-face-3
51 '((t (:foreground "palegreen1" :weight bold)))
52 "Face for MAD-X beamline components keywords.")
53(defface madx-keyword-face-4
54 '((t (:foreground "darkturquoise" :weight bold)))
55 "Face for MAD-X parameters keywords.")
56(defface madx-keyword-face-5
57 '((t (:foreground "wheat" :weight bold)))
58 "Face for MAD-X analysis and control keywords.")
59
60;; -- [3-2] キーワード群の列挙 -- ;;
61(setq madx-keywords-1 ;; 1 - controls ;;
62 '( "if" "elseif" "else" "while" "macro" "error" "ealign" "efcomp" "seterr" ":=" "->" ))
63(setq madx-keywords-2 ;; 2 - commands ;;
64 '("plot" "table" "tabindex" "tabstring" "twiss" "ibs" "line" "makethin" "aperture" "sixtrack" "dynap" "emit" "match" "endmatch" "vary" "constraint" "weight" "global" "gweight" "ptc_twiss" "ptc_printparametric" "ptc_normal" "select_ptc_normal" "ptc_track" "ptc_track_line" "ptc_create_universe" "ptc_create_layout" "ptc_read_errors" "ptc_move_to_layout" "ptc_align" "ptc_end" "ptc_track_end" "start" "run" "ptc_observe" "observe" "ptc_start" "ptc_setswitch" "ptc_knob" "ptc_setknobvalue" "match withptcknobs" "ptc_printframes" "ptc_select" "ptc_select_moment" "ptc_dumpmaps" "ptc_eplacement" "ptc_varyknob" "end_match" "ptc_moments" "ptc_setcavities" "ptc_setdebuglevel" "ptc_setaccel_method" "ptc_setexactmis" "ptc_setradiation" "ptc_settotalpath" "ptc_settime" "ptc_setfringe" "exit" "quit" "stop" "help" "show" "value" "option" "exec" "set" "system" "title" "use" "select" "assign" "call" "return" "print" "printf" "renamefile" "copyfile" "removefile" "create" "delete" "readtable" "readmytable" "write" "setvars" "setvars_lin" "fill" "shrink" "beam" "resbeam" "seqedit" "flatten" "cycle" "reflect" "install" "move" "remove" "replace" "extract" "endedit" "save" "dumpsequ" "savebeta" "coguess" "const" "eoption" "esave" "real" "lmdif" "migrad" "simplex" "jacobian" "use_macro" "correct" "usemonitor" "usekick" "csave" "setcorr" "coption" "sodd" "survey" "sxfread" "sxfwrite" "touschek" "track" "endtrack" ))
65(setq madx-keywords-3 ;; 3 - beamlines ;;
66 '("drift" "quadrupole" "sextupole" "octupole" "solenoid" "crabcavity" "rfcavity" "dipedge" "multipole" "collimator" "ecollimator" "rcollimator" "yrotation" "srotation" "translation" "changeref" "marker" "rbend" "sbend" "hkicker" "vkicker" "kicker" "tkicker" "elseparator" "hmonitor" "vmonitor" "monitor" "instrument" "placeholder" "beambeam" "matrix" "nllens" "rfmultipole"))
67(setq madx-keywords-4 ;; 4 - parameters ;;
68 '("file" "sequence" "endsequence" "refer" "particle" "energy" "flag" "haxis" "vaxis" "column" "betx" "bety" "positron" "electron" "proton" "antiproton" "posmuon" "negmuon" "ion" "pi" "twopi" "degrad" "raddeg" "e" "emass" "pmass" "nmass" "mumass" "clight" "qelect" "hbar" "erad" "prad" "true" "false" "simple" "collim" "teapot" "hybrid" "entry" "centre" "exit" "circle" "rectangle" "ellipse" "lhcscreen" "marguerite" "rectellipse" "racetrack" "octagon" "terminal"))
69(setq madx-keywords-5 ;; 5 - math ;;
70 '("sqrt" "log" "log10" "exp" "sin" "cos" "tan" "asin" "acos" "atan" "sinh" "cosh" "tanh" "sinc" "abs" "erf" "erfc" "floor" "ceil" "round" "ranf" "gauss" "tgauss" "flat5" "flat56"))
71
72;; -- [3-3] キーワードとフェイスを対応 (case-insensitive) -- ;;
73(defvar madx-font-lock-keywords
74 `((,(regexp-opt madx-keywords-1 'words) . 'madx-keyword-face-1)
75 (,(regexp-opt madx-keywords-2 'words) . 'madx-keyword-face-2)
76 (,(regexp-opt madx-keywords-3 'words) . 'madx-keyword-face-3)
77 (,(regexp-opt madx-keywords-4 'words) . 'madx-keyword-face-4)
78 (,(regexp-opt madx-keywords-5 'words) . 'madx-keyword-face-5)))
79
80
81;; ---------------------------------------- ;;
82;; [4] @var #var (マクロ記号) ;;
83;; ---------------------------------------- ;;
84(defface at-variables-face-in-madx
85 '((t (:foreground "orange" :weight bold)))
86 "Face for @var identifiers inside strings.")
87
88(defun highlight-at-variables-in-madx ()
89 "Highlight @variable (#variable) patterns inside strings."
90 (font-lock-add-keywords
91 nil
92 '(("[@#][a-zA-Z0-9_.]+"
93 (0 'at-variables-face-in-madx prepend)))))
94
95;; ---------------------------------------- ;;
96;; [5] 文字列 ハイライト ;;
97;; ---------------------------------------- ;;
98(defface strings-face-in-madx
99 '((t (:foreground "BurlyWood" :weight normal)))
100 "Custom face for strings in madx-mode")
101
102(defun highlight-strings-in-madx ()
103 "Highlight strings in MADX with custom face."
104 (font-lock-add-keywords
105 nil
106 '(("\"\\([^\"\\]\\|\\\\.\\)*\""
107 (0 'strings-face-in-madx prepend)))))
108
109;; ---------------------------------------- ;;
110;; [6] 数字 ハイライト ;;
111;; ---------------------------------------- ;;
112(defface numbers-face-in-madx
113 '((t (:foreground "Cyan" :weight normal)))
114 "Face for numbers in MADX.")
115
116(defun highlight-numbers-in-madx ()
117 "Highlight numbers in MADX with a custom face."
118 (font-lock-add-keywords
119 nil
120 '(("\\(?:^\\|[^a-zA-Z0-9_.]\\)\\(-?[0-9]+\\(?:\\.[0-9]+\\)?\\(?:[eE][-+]?[0-9]+\\)?\\)"
121 (1 'numbers-face-in-madx prepend)))))
122
123(defun highlight-numbers-inside-strings-in-madx ()
124 "Highlight numbers even inside strings."
125 (font-lock-add-keywords
126 nil
127 '(("\"[^\"]*?\\([0-9]+\\(?:\\.[0-9]+\\)?\\(?:[eE][-+]?[0-9]+\\)?\\)[^\"]*?\""
128 (1 'numbers-face-in-madx prepend)))))
129
130(defun highlight-comments-override-in-madx ()
131 "Forcefully highlight comments to override other face rules."
132 (font-lock-add-keywords
133 nil
134 '(("//\\(.*\\)$" ; キャプチャグループ1に色をつける
135 (0 'font-lock-comment-face prepend)))))
136
137
138;; ---------------------------------------- ;;
139;; [7] フックする拡張子 の設定 ;;
140;; ---------------------------------------- ;;
141(add-to-list 'auto-mode-alist '("\\.madx\\'" . madx-mode))
142
143;; ---------------------------------------- ;;
144;; [8] インデント ;;
145;; ---------------------------------------- ;;
146;; --- 全部スペースでインデント --- ;;
147(add-hook 'javascript-mode-hook '(lambda() (setq indent-tabs-mode nil)))
148
149;; --- 全部スペースでインデント --- ;;
150(defun madx-inside-sequence-p ()
151 "Return non-nil if the current line is inside a SEQUENCE...ENDSEQUENCE block."
152 (save-excursion
153 (let ((seq-pos nil)
154 (endseq-pos nil))
155 ;; 現在行より前の SEQUENCE を探す
156 (when (re-search-backward "^[ \t]*SEQUENCE\\b" nil t)
157 (setq seq-pos (point)))
158 (goto-char (point-at-bol))
159 ;; 現在行より後の ENDSEQUENCE を探す
160 (when (re-search-forward "^[ \t]*ENDSEQUENCE\\b" nil t)
161 (setq endseq-pos (point)))
162 ;; どちらも見つかり、かつ現在位置がその間なら t
163 (and seq-pos endseq-pos
164 (> endseq-pos (point))
165 (< seq-pos (point))))))
166
167(defun madx-indent-line ()
168 "Indent current line if inside SEQUENCE...ENDSEQUENCE block."
169 (interactive)
170 (let ((indent (if (madx-inside-sequence-p) tab-width 0)))
171 (save-excursion
172 (beginning-of-line)
173 (delete-horizontal-space)
174 (indent-to indent))
175 (when (looking-back "^[ \t]*" (line-beginning-position))
176 (back-to-indentation))))
177
178;; ---------------------------------------- ;;
179;; provide ;;
180;; ---------------------------------------- ;;
181(provide 'madx-mode)
作成の要点¶
[1] モード定義部分¶
define-derived-mode より、
prog-mode
等から派生モードを作成.コメント記号を
//
などから変更highlight 関数を増やした場合、追加.
[2] 演算子記号 ハイライト¶
含める 演算子記号 を変更
色
[3] キーワード ハイライト¶
[3-1] : フォントフェイス = 色 と説明書きを変更
[3-2] : キーワード群 = キーワードを小文字 で列挙 ( case-insensitive にしている.)
[3-3] : キーワードとフェイスを対応.
[4] @var マクロ記号 ハイライト¶
マクロ指定にする記号( @var1 などをマクロとして、後ほど置換するのに使用 )を変更
色
[5] 文字列ハイライト¶
色
[6] 数字ハイライト¶
色
[7] 拡張子¶
フックする拡張子を指定
[8] インデント¶
現状、うまく機能していない(工事必要).
まとめ¶
上記項目の変更により、手早くハイライトシンタックスを作成する.