elisp

elisp

elisp

私にとってelispが必要になるのは半年に一回あるかどうかである。その度に、本をひっくりかえしたり、ウェブを検索してきた。このさい、メモに残しておいて、効率よく仕事をしたい。

内容は、ほとんどが「やさしい Emacs-Lisp」(旧版)にそっている。

基本的なもの

ポイントに関わるもの

現在のポイント位置を知る

(setq aa 
(point)
)   ; aaに現在のポイント位置が入る。バッファの先頭は「1」

バッファの先頭・末尾に行く

;; (point-min), (point-max)はバッファの先頭(末尾)位置のポイントを返す関数
(goto-char 
(point-min)
)  ; バッファの先頭に移動
(goto-cahr 
(point-max)
)  ; バッファの末尾に移動

行頭と行末

(beginning-of-line)  ; 行頭へ移動
(end-of-line)        ; 行末へ移動

行・行数に関するもの

1行進む

(forward-line 1)
    ; 1行進みポイント位置は行頭にある。
;;                    バッファ末尾で呼び出してもエラーにならない

ポイント位置の行数を知る

(setq aa (
count-lines
 (point-min) (point)))  ; 最初の行は「1」

バッファの最後まで1行ずつ処理する例

(while (not (eobp))を使う

(defun ttt-eobp ()
  "バッファの最後まで1行ずつ処理する例"
  (interactive)
  (let ((aa 0))
    (goto-char (point-min))  ; バッファの先頭に
    
(while (not (eobp))
      ; eobp(end of buffer point)
      (setq aa (1+ aa))
      (forward-line 1)
)
      ; 1行進む
    (message "aa=%d" aa)     ; 行数を表示
    (sit-for 3)))

1行完全に削除

http://www.emacswiki.org/emacs/ElispCookbook#toc13より

(let ((beg (progn (forward-line 0)
                   (point))))
   (forward-line 1)
   (delete-region beg (point)))

キーボードから入力

メニュー等のメッセージを表示して、入力を待つ

入力は文字列になり、Enterが押されると次に進む

(defun ttt-message ()
  "バッファにメッセージを表示して入力を得る"
  (interactive)
  (let (mbuf input)  ; 変数の宣言のみなのでinputの初期値はnil
    (setq mbuf (get-buffer-create "*mytest*"))
    (switch-to-buffer mbuf)
    (insert "バッファにメッセージを出して、入力を得る
             この行は2行目に表示されます\n
             この行は4行目に表示されますです\n\n")
    (while (not input)        ; このループでenterを待ちます
      (setq input (
read-string
 "入力後,Enterを押してください==>")))
    (message "入力=%s" input)
    (sit-for 3)
    (kill-buffer nil)))   ; バッファを削除します

ミニバッファから入力する

1文字だけの入力であり、いちいちEnterを押す必要がない

(defun ttt-minibuf ()
  "ミニバッファに表示し、入力(1文字)を得る"
  (interactive)
  (let (input)  ; 変数の宣言のみなのでinputの初期値はnil
    (while (not input)
      (message "入力してください ==>")
      ; read-char はキーボードから1文字読み込んで文字コードを返す
      ; char-to-string は文字コードを対応する文字に変換
      (setq input 
(char-to-string (read-char)
)))
    (message "入力=%s" input)
    (sit-for 3)))

(「やさしいEmacs-Lisp」より)

インタラクティブ関数 (p15)

c 文字
d ディレクトリ名
f ファイル名
n 数値
p C-u predixで与えた数値(ディフォルトは1)
P C-u predixで与えた数値(ディフォルトはnil)
r 関数起動時に設定されているポイントとマークの2数値
s 文字列

ラムダ式 (p17)

symbol-function 引数として与えたシンボルの関数定義を返す

変数 (p18)

set シンボル値への値の代入
setq 変数への代入
defvar 変数の定義。値が代入されるのは、変数が未定義の場合の時
let 関数内部で局所的に利用する変数を作る
let* 変数内部でそれ以前に宣言した変数を参照できる

制御構造

条件 (p22)

(if 式 from1 from2 ..)
式がnil以外はform1,2,..
(and from1 form2 ..)
式を順次評価しnilになる式があった時点で打ち切りnilを返す。すべての式がnon-nilの場合は最後の式の値を返す
(or form1 form2 ..)
式を順次評価しnon-nilになる式があった時点で打ち切り、その値を返す
(cond ….)
複数の条件分岐を作る時に用いる
    (setq aa 0)				; => 0
    (cond ((= aa 1) (setq bb 1))
      ((= aa 2)	(setq bb 2))
      ((= aa 3)	(setq bb 3))
      (t (setq bb 4)))			; => 4 bb=4で条件を抜ける

エラー処理

すべての関数の実行を取りやめる

(error "開始位置のカーソルは#のある行にしてください")

数値、算術関数、型変換

数値(整数、浮動小数点の扱い、数値かどうかの判断、用意されている算術関数、型変換関数、書式付き文字列の変換など

演算子

加算 + 減算 乗算 * 除算 /
剰余 % 1加算 1+ 1減算 1-

サンプル 足し算


(setq tasizan (+ 2 3))         ;  変数tasizan ==> 5
(setq tasizan (1+ tasizan))    ;  変数tasizan =-> 6

数値比較用関数

< , <= ,= , /=, >, >=

上記は数値の比較のみ。文字列、t,nilの比較はstring=, eqなど

サンプル 比較


(if (< 8 5)
    (message "真")
  (message "偽"))              ; "偽"と表示される

数値型変換関数

float 整数を浮動小数点に変換
round 浮動小数点を小数点以下一桁で四捨五入し整数に丸める
floor 浮動小数点の小数点以下を切り捨てて整数化する
ceiling 浮動小数点の少数点以下を切り上げて整数化する

型変換関数

;  数値を文字列に
(setq aa 123)
(number-to-string aa)   	; => "123"
;  数値文字列を数値に
(setq bb "456")
(string-to-number bb)   	; => 456
;  文字列の先頭の1文字の文字コードを得る
(setq cc "abc")
(string-to-char cc)		; => 97
;  文字コードに対応する文字1文字で構成される文字列
(setq dd 98)
(char-to-string dd)		; => "b"

述語関数

numberp 引数が数値ならt, そうでなればnil を返す
integerp 引数が整数ならt, そうでなればnil を返す
floatp 引数が浮動小数点ならt, そうでなればnil を返す

文字列

特殊文字

文字列操作

substring : 部分文字列を返す
(setq aa "abcdef")
(substring aa 1 4)  ; ==> "bcd"
upcase, downcase : 引数の文字列を大文字、小文字に変換
(setq aa "abcdef")
(upcase aa)  ; ==> "ABCDEF"
stringp : 引数が文字列かどうか検査。文字列ならt
(let ((aa 1) (bb "1"))
  (stringp aa)  ; ==> nil
  (stringp bb)  ; ==> t
string= : 2つの文字列引数が等しければt
(let ((aa "abc") (bb "abcd"))
  (string= aa bb)) ; ==> nil

tips

インデントの整形
1行だけの場合はtab。複数行は選択後C-M-\
バッファ内の関数定義に飛ぶ
カーソルを飛びたい関数名に置いたままで、M-x imenuとキーイン。キーインした時の関数名がディフォルトで表示される。元に戻るのは、C-u C-SPC。ファイルをまたがった関数名のジャンプにはetagsというものがあるらしい。