/usr/share/emacs/site-lisp/tiarra-conf/tiarra-conf.el is in tiarra-conf-el 20100212-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | ;; -*- emacs-lisp -*-
;; ----------------------------------------------------------------------------
;; $Id: tiarra-conf.el 11365 2008-05-10 14:58:28Z topia $
;; ----------------------------------------------------------------------------
;; tiarra.conf編集用モード。
;; ----------------------------------------------------------------------------
;; キーマップ
(defvar tiarra-conf-mode-map
(let ((map (make-keymap)))
(define-key map "\M-n" 'tiarra-conf-next-block)
(define-key map "\M-p" 'tiarra-conf-prev-block)
(define-key map [?\C-c?\C-.] 'tiarra-conf-jump-to-block)
(define-key map "\C-c." 'tiarra-conf-jump-to-block)
map)
"Keymap for tiarra conf mode.")
;; 構文定義
(defvar tiarra-conf-mode-syntax-table nil
"Syntax table used while in tiarra conf mode.")
(if tiarra-conf-mode-syntax-table
() ; 構文テーブルが既存ならば變更しない
(setq tiarra-conf-mode-syntax-table (make-syntax-table))
(modify-syntax-entry ?{ "(}")
(modify-syntax-entry ?} "){"))
;; 略語定義
(defvar tiarra-conf-mode-abbrev-table nil
"Abbrev table used while in tiarra conf mode.")
(define-abbrev-table 'tiarra-conf-mode-abbrev-table ())
;; フック
(defvar tiarra-conf-mode-hook nil
"Normal hook runs when entering tiarra-conf-mode.")
(defun tiarra-conf-mode ()
"Major mode for editing tiarra conf file.
\\{tiarra-conf-mode-map}
Turning on tiarra-conf-mode runs the normal hook `tiarra-conf-mode-hook'."
(interactive)
(kill-all-local-variables)
(use-local-map tiarra-conf-mode-map)
(set-syntax-table tiarra-conf-mode-syntax-table)
(setq local-abbrev-table tiarra-conf-mode-abbrev-table)
(setq mode-name "Tiarra-Conf")
(setq major-mode 'tiarra-conf-mode)
;; フォントロックの設定
(make-local-variable 'font-lock-defaults)
(setq tiarra-conf-font-lock-keywords
(list '("^[\t ]*#.*$"
. font-lock-comment-face) ; コメント
'("^[\t ]*@.*$"
. font-lock-warning-face) ; @文
'("^[\t ]*\\+[\t ]+.+$"
. font-lock-type-face) ; + モジュール
'("^[\t ]*-[\t ]+.+$"
. font-lock-constant-face) ; - モジュール
'("^[\t ]*\\([^:\n]+\\)\\(:\\).*$"
(1 font-lock-variable-name-face) ; key
(2 font-lock-string-face)) ; ':'
'("^[\t ]*[^{}\n]+"
. font-lock-function-name-face))) ; ブロック名
(setq font-lock-defaults '(tiarra-conf-font-lock-keywords t))
;; mmm-modeの設定
(if (featurep 'mmm-auto)
(progn
(mmm-add-group
'embedding-in-tconf
'((pre-in-tconf
:submode perl
:front "%PRE{"
:back "}ERP%")
(code-in-tconf
:submode perl
:front "%CODE{"
:back "}EDOC%")))
(setq mmm-classes 'embedding-in-tconf)
(mmm-mode-on)))
(run-hooks 'tiarra-conf-mode-hook))
(defun tiarra-conf-next-token ()
"カレントバッファの現在のカーソル位置から次のトークンを探して返す。
カーソルはそのトークンの終はりの位置へ移動する。
返されるのは次のやうなリストである。
\(\"トークン\" '種類)
種類:
pair -> キーと値のペア
label -> ブロックのラベル
blockstart -> ブロックの開始記號
blockend -> ブロックの終了記號
トークンが無ければnilを返す。"
(catch 'tiarra-conf-next-token
;; まずは空白とコメントを飛ばす。
;; @文も%PREも%CODEも飛ばす。
;; ……しかし「最小一致」の使へないElisp-Regexで
;; どうやつて%PREに一致させたものだか分からない。
;; 助けて。
(or (re-search-forward "^\\([\n\t ]\\|#.*\\|@.*\\)*" nil t 1)
(throw 'tiarra-conf-next-token nil))
;; "キー: 値"の形式であれば、行の終はりまでがトークン。
(let* ((keychar "[^{}:\n\t ]") ; キーとして許される文字
(pair (concat keychar "+[\t ]*:.*")) ; キーと値のペア
;; 連續する二つのコロンは、特例としてラベル名に許す。
(labelchar "\\([^-{}\n\t ]\\|::\\)") ; ブロック名として許される文字
(label (concat "\\(\\(\\+\\|-\\)[\t ]+\\)?" labelchar "+")) ;; ブロックのラベル
(blockstart "{") ;; ブロックの開始
(blockend "}") ;; ブロックの終了
type)
(setq type
(cond ((looking-at pair) 'pair)
((looking-at label) 'label)
((looking-at blockstart) 'blockstart)
((looking-at blockend) 'blockend)))
(if (null type)
nil
(prog1 (list (buffer-substring (point) (match-end 0))
type)
(goto-char (match-end 0)))))))
(defun tiarra-conf-next-block (&optional n)
"次からn番目のブロックの位置へカーソルを移動する。
nは省略可能で、省略された場合は`1'。
ブロックが見付かつた場合は、そのラベルの開始位置を返す。"
(interactive "p")
(catch 'tiarra-conf-next-block
(setq n (if (numberp n) n 1))
(if (< n 0)
(throw 'tiarra-conf-next-block (tiarra-conf-prev-block (* -1 n))))
(if (= n 0)
(throw 'tiarra-conf-next-block nil))
;; カーソルを行の先頭へ移動。
(beginning-of-line)
(let (result token)
;; labelが來るまでトークンを探す。
(while (progn
(setq token (tiarra-conf-next-token))
;; tokenがnilまたはlabelなら終了。
(if (or (null token)
(eq (cadr token) 'label))
nil
;; label以外のトークンなので、再度檢索。
t)))
(if (null token)
;; トークンが無い。ここで終はり。
nil
(setq result (point))
;; "{"の次の非空白文字へ移動。
(re-search-forward "{" nil t 1)
(re-search-forward "[^\n\t ]" nil t 1)
(backward-char)
;; nが2以上だったらもう一度。
(if (> n 1)
(tiarra-conf-next-block (1- n))
result)))))
(defun tiarra-conf-prev-block (&optional n)
"前からn番目のブロックの位置へカーソルを移動する。
nは省略可能で、省略された場合は`1'。
ブロックが見付かつた場合は、そのラベルの開始位置を返す。"
(interactive "p")
(catch 'tiarra-conf-prev-block
(setq n (if (numberp n) n 1))
(setq n (1+ n))
(if (< n 0)
(throw 'tiarra-conf-prev-block (tiarra-conf-next-block (* -1 n))))
;; まづ次のブロックを探して、その位置を記録する。nilならnilで良い。
(let ((next-block-pos
(save-excursion (tiarra-conf-next-block)))
current-block-pos)
;; 一行づつカーソルを前に戻しつつ、「次の」ブロックを探してみる。
;; next-block-posよりも前に存在するブロックを見付けたら、そこで止める。
(while (progn
(beginning-of-line)
(if (= (point) (point-min))
;; これ以上前には戻れない。
nil
;; まだ戻れる。
(previous-line)
(setq current-block-pos
(save-excursion (tiarra-conf-next-block)))
;; 最初に見付けた「次の」ブロックがnilだつたり、
;; 今囘見付けた「次の」ブロックと最初のそれが異つてゐたりすれば
;; これを返して終了する。でなければ同じ事を繰返す。
(eq current-block-pos next-block-pos))))
;; nが2以上だつたらもう一度。
(if (> n 1)
;; カーソル位置を先頭へ戻す
(progn (beginning-of-line)
(tiarra-conf-prev-block (- n 2)))
;; カーソルを適切な位置へ移動させる爲だけに
;; tiarra-conf-next-blockを呼ぶ。
(tiarra-conf-next-block)
current-block-pos))))
(defun tiarra-conf-join (delimitor sequence)
"perlのjoin(delimitor, sequence)と同じ。"
(let (result join)
(setq join (lambda (elem)
(setq result (if (null result)
elem
(concat result delimitor elem)))))
(mapcar join sequence)
result))
(defun tiarra-conf-jump-to-block ()
"そのconf中にあるブロックの名前を入力し、その場所にジャンプするコマンド。"
(interactive)
(let (comp-list ;; competing-readで使ふalist ("ブロック名" . labelトークンの直後の位置)
parsing-block-stack ;; ("ブロック名" ...)
blockname-to-jump
point-to-jump)
(save-excursion
;; カーソルをファイルの先頭へ
(goto-char (point-min))
;; 一つづつトークンを見て行く。labelを見たら記録する。
(while (let (token type blockname)
(setq token (tiarra-conf-next-token))
(if (null token)
;; もうトークンが無い。
nil
(setq type (cadr token))
(cond ((eq type 'label)
;; ブロック(・∀・)カイシ
(setq blockname (car token))
(if (string-match "^[-+][\t ]+" blockname) ; +や-は取る。
(setq blockname (replace-match "" nil nil blockname)))
(push blockname parsing-block-stack)
(setq comp-list
(append comp-list
(list (cons
(tiarra-conf-join " - " (reverse parsing-block-stack))
(point))))))
((eq type 'blockend)
;; ブロック(・A・)シュウリョウ
(pop parsing-block-stack)))
t)))
;; ブロック名を聞く。
(let ((completion-ignore-case t)) ; 一時的にこの變數をtに。動的スコープは便利だね…。
(setq blockname-to-jump (completing-read
"ジャンプするブロック: "
comp-list nil t)))
(setq point-to-jump (cdr (assoc blockname-to-jump comp-list))))
(if point-to-jump
;; 適切な位置へカーソルを移動
(progn
(goto-char point-to-jump)
(beginning-of-line)
(tiarra-conf-next-block)))))
|