メジャーモード (1) - 基本と例 -

目的

  • Emacs では、拡張子毎に 機能・動作・見た目を規定できる.( Major Mode )

  • 設定用言語: *Emacs-Lisp* は難解な言語まともに付き合うのはおすすめしない

  • コピペとChatGPT先生と最小限の変更で、世に言う 「オレオレモード」 を インスタントに実現すべき

本ページの解説目標は、下記.

  • 拡張子を自動判別し、モードを開く.

  • 好きなワードをハイライトする.


Emacs-Lisp Major Mode

サンプルコード

ハイライト用 Major Mode のサンプルコード
 1;; ========================================================= ;;
 2;; === .sif mode Emacs Major Mode                        === ;;
 3;; ========================================================= ;;
 4
 5;; -- generic mode として定義                    -- ;;
 6(require 'generic-x)
 7
 8;; -- リストインターリーブ関数の定義             -- ;;
 9(defun list-interleave (ls res inserting)
10  (cond
11   ((not ls)  (reverse res))
12   ((not res) (list-interleave (cdr ls) (cons (car ls) res) inserting))
13   (t (list-interleave
14       (cdr ls)
15       (cons (car ls) (cons inserting res))
16       inserting))))
17
18;; -- .sif 変数型群の定義 ( 変数グループの定義 ) -- ;;
19(defvar sif-variables-type-operators
20  (apply 'concat (list-interleave
21                  '("String" "Real" "Logical" "Integer" "None")
22                  '() "\\|")))
23
24;; -- .sif 読み込み時の動作を指定する関数        -- ;;
25(defun sif-initial-call ()
26  '( (setq indent-tabs-mode nil)
27     (setq tab-width 2)
28     )
29  )
30
31;; ------------------------------------------------ ;;
32;; -- .sif Major Mode の定義                     -- ;;
33;; ------------------------------------------------ ;;
34
35;; -- generic-mode 名 :: sif-mode                -- ;;
36(define-generic-mode 'sif-mode
37  ;; 1. コメント行の印
38  '("!" "#")
39  ;; 2. とりあえずハイライトするキーワード群     -- ;;
40  '("Header" "Constants" "Material" "End" "Solver" "Boundary Condition"
41    "Simulation" "Body" "Body Force" "Initial Condition" "Equation" "Components")
42  ;; 3. 詳細な区別でハイライトするキーワード群   -- ;;
43  `( ("\sw"
44      . font-lock-string-face)
45     (,sif-variables-type-operators
46      . font-lock-type-face)
47     )
48  ;; -- 3.1 :: ダブルクォーテーションされた文字 :: string-face として表示 -- ;;
49  ;; -- 3.2 :: 上の関数に示した文字列           :: type-face   として表示 -- ;;
50  ;; -- 
51  ;; 4. file name ( 拡張子の指定 => \\.***$ )
52  '("\\.sif$")
53  ;; 5. hook function ( 起動時に実行する関数 無ければ nil, もしくは、上記関数で定義. )
54  '( sif-initial-call )
55  ;; 6. explanation   ( モードの説明書、呼び出された時になんて表示されるか. )
56  "sif mode for elmer FEM environment"
57  )
58
59;; ------------------------------------------------ ;;
60;; -- 拡張子との連想                             -- ;;
61;; ------------------------------------------------ ;;
62
63;; (add-to-list 'auto-mode-alist '("\\.sif\\'" . sif-mode))

コード の動作

  • Major Mode の基本の定義は、 ( define-generic-mode ... ) を書く.

  • 次の7つの指定で定義.

    1. モード名 ( sif-mode )

    2. コメント行の開始文字

    3. とりあえずハイライトする文字列群の指定

    4. 詳細なハイライト文字列の指定

    5. 反応する拡張子の指定

    6. ファイルが開かれた際の自動実行する関数

    7. モードの説明文 ( ミニバッファに表示される )

  • モード定義部分以外の変更必要箇所は、次の2つ.

    1. 変数グループを返却する関数 ( sif-variables-type-operators )

    2. 読み込み時の動作を定義する関数 ( sif-initial-call )

    • 変数グループは、関数名 ( グループ名 )と中身の文字列リスト ( '() としてリストを定義 )を変更する.

    • 動作を定義する関数は好きなように変更して良い.何かパラメータを設定したければ、

パラメータ名の指定

(setq パラメータ名 )
  • 何も動作が必要無ければ、sif-initial-call の代わりに nil (何もしない)を書いても良い.

  • 末尾の拡張子へのフックは書かなくても、ファイルを開いた時に自動的に判別される.

  • 一応、一般のモードフックの方法を示すためにコメントにて記述している.