Emacsでバッファから文字列を取得するやり方

バッファからの文字列取得の仕方がわからなかったのでメモしておく。
バッファからの文字列取得は

  1. buffer-substring
  2. buffer-substring-no-propeties
  3. buffer-string

3つがあるっぽい。この内、buffer-stringは文字列のテキスト属性をもってるため、そのまま文字列を加工するための用途じゃないと思う。ほかの2つはバッファの文字列を加工するために使える。

buffer-substring、buffer-substring-no-propertiesは「1〜n-1」というよくわからない範囲をとるため、そこは気を付けないといけないと思う。

>>>> 追記 2012/5/1
そんなことはなかった。というかひどい間違いをした。
引数として取る値の範囲は「1〜n+1」です。
Emacsの内部的には「0〜n」というだけだった。<<<<
assertもちょこっと載せておく。assertを使ったテストはbuffer-substring-no-propertiesしか仕方がわからない...。

以下のやり方は*scratch*などのまっさらなバッファでやってる。末尾の改行ありません

バッファの文字の一部を取得する

test-string

という文字列があったとする。(11文字)

テキスト属性がありの場合と、なしの場合の関数がある。

;;テキスト属性あり
(buffer-substring 1 5)
;=> #("test" 0 4 (fontified t))
;;テキスト属性なし
(buffer-substring-no-properties 1 5)
;=> "test"
(assert (string= "test" (buffer-substring-no-properties 1 5)))
;=> nil

バッファの全文字列を取得する

test-string1
test-string2

(一行目は12文字分、2行目も12文字)

;;テキスト属性あり
(buffer-string)
;=> #("test-string1
;   test-string2" 0 13 (fontified t) 13 25 (fontified t))
;;テキスト属性なし
(buffer-substring-no-properties (point-min) (point-max))
;=> "test-string1
;    test-string2" 
; ↑はC-jの場合
; 実際の値は
;=> "test-string1\ntest-string2"

この場合のassertは

(assert (string= "test-string1\ntest-string2"
                 (buffer-substring-no-properties (point-min) (point-max))))
;=> nil

もし、test-string2のあと(バッファの最後に)に改行があった場合はこのassertは失敗になる。

@see GNU Emacs Lisp¥ê¥Õ¥¡¥ì¥ó¥¹¥Þ¥Ë¥å¥¢¥ë: Buffer Contents


そういえば、auto-complete.elとかanything.elとかで、buffer-substring-no-propertiesがたまに使われてた。