逆引きxyzzy lisp(バッファ) - circleratio/xyzzy GitHub Wiki

目次

バッファ自体の操作

バッファを作成する

(create-new-buffer "*test*")

create-new-buffer は、既に同名のバッファがある場合、<2>, <3>, ... の添え字が付いた新しいバッファを作成する。

(get-buffer-create "*test*")

get-buffer-create は、既に同名のバッファがある場合、そのバッファを返す。

(switch-to-buffer "*test*")

switch-to-buffer は、既に同名のバッファがある場合、そのバッファを返す。 指定したバッファを操作中のウィンドウに表示する点が get-buffer-create との相違点。

バッファを切り替える

(set-buffer (get-buffer-create "lisp.txt")))

バッファの名前を得る

(buffer-name (selected-buffer))

バッファの大きさを得る

(buffer-size)

バッファを削除する

(delete-buffer "*test*")

delete-buffer は削除するかどうかの確認をしない。

(kill-buffer "*test*")

kill-bufferは、バッファが変更されていると、削除するかどうかを対話的に確認する。 マクロで使うなら確認を行わない delete-buffer を使ったほうがよいことが多い。

(kill-selected-buffer)

現在選択しているバッファを削除する。

(kill-all-buffers)

すべてのバッファを削除する。 マクロで使うことは基本的にないと思われる。

バッファの文字コードを指定する

(set-buffer-fileio-encoding *encoding-sjis*)

バッファの改行文字を指定する

(set-buffer-eol-code 1)

0がlf, 1がcrlf, 2がcr, 3がcrlf.

バッファ一覧を取得する

(buffer-list)
=> (#<buffer:  *Completion*> #<buffer:  *Minibuf0*> #<buffer: *Buffer List*> #<buffer: *scratch*>)

カレントバッファを得る

emacs では current-buffer だけど,xyzzy では selected-buffer なので注意.

(selected-buffer)
=> #<buffer: *scratch*>

表示オプションを設定する

行番号の表示を有効にし,改行とEOFの表示を無効にする例.

(let ((buf (selected-buffer)))
  (set-local-window-flags buf
                          (+ *window-flag-line-number*)
                          t)
  (set-local-window-flags buf
                          (+ *window-flag-newline*
                             *window-flag-eof*)
                          nil))

バッファを読み取り専用にする

(toggle-read-only t)

バッファが更新されても,バッファを閉じる際に確認しない

(make-local-variable 'need-not-save)
(setq need-not-save t)

バッファ内での操作

テキストを挿入する

(insert "ab" "cd" "ef")
=> abcdef

(insert "ab" 4)
=> abababab

(insert "ab" "cd" 2)
=> abcdabcd

(insert "ab" 2 "cd" 2)
=> 不正なデータ型です: 2: (or string character)

(insert #¥a #¥b "c" "d")
=> abcd

(insert #¥a 5)
=> aaaaa

カレントバッファにファイルを読み込む

(find-file "/tmp/test.txt")

バッファ全体の内容をコピーする

(buffer-substring (point-min) (point-max))

バッファの指定範囲の内容をコピーする

(buffer-substring from to)

バッファ内の空行を削除する

(replace-regexp "^¥n" "" t)

バッファの内容をクリアする

(delete-region (point-min) (point-max))

erase-buffer でもバッファの内容をクリアできるが,作業途中でバッファの内容をクリアする際にはこちらのやりかたのほうがよい. erase-buffer だと「知らない間にファイルの日付が変わっています」と文句を言われるようになるため.

バッファ内の文字列を置換する

現在のカーソル位置以降のテキストに対して置換が行われる.

(replace-string "nil" "x" :noerror)

(replace-buffer "[a-z]¥¥{2¥¥}" "XXXX" :regexp t)

カーソル

カーソルを移動する

カーソルを前後に移動させる

(forward-char)
(backward-char)

バッファ先頭に移動する

beginning-of-buffer の場合、カーソルが元あった位置にマークが設定される。

(goto-char (point-min))

(beginning-of-buffer)

バッファ末尾に移動する

end-of-buffer の場合、カーソルが元あった位置にマークが設定される。

(goto-char (point-max))

(end-of-buffer)

バッファ内の任意の位置へ移動する

(goto-char 10)

行頭、行末へ移動する

(goto-bol)

(goto-eol)

行内で任意のカラム位置に移動する

(goto-column 5)

前後の行に移動する

引数を省略した場合は1行ずつ移動する.

(previous-line)
=> t

(next-line 2)
=> t

指定された行に移動する

(goto-line 5)

文字列を検索して移動

テキストの検索には scan-buffer を使う。 Emacs Lisp では search-forward や search-backward などいくつかの関数があるが、xyzzy Lisp では scan-buffer に統一されているので注意すること。

(scan-buffer "[a-z]+" :regexp t)
=> t

(match-string 0)
=> "scan"

(match-beginning 0)
=> 21

(match-end 0)
=> 25

現在のカーソル位置を取得する

(point)

カーソル位置で文字列のマッチを行う

検索方向 正規表現 関数
前方 あり looking-at
前方 なし looking-for
後方 あり 自前で用意すること
後方 なし looking-back
(defun check-parenthesis-at-bol ()
  (interactive)
  (if (looking-at "^(")
      (message "OK")
    (message "NG")))

(defun check-empty-parenthesis ()
  (interactive)
  (if (looking-for "()")
      (message "OK")
    (message "NG")))

(defun check-empty-parenthesis-backward ()
  (interactive)
  (if (looking-back "()")
      (message "OK")
    (message "NG")))

looking-at の後方版。

(defun looking-at-backward (regexp &optional case-fold)
  (save-excursion
    (save-restriction
      (narrow-to-region (point-min) (point))
      (goto-char (point-min))
      (scan-buffer (format nil "¥¥(?:‾A¥¥)¥¥'" regexp)
		   :regexp t :case-fold case-fold))))

カーソルがファイルの最終行かどうか調べる

(defun end-line-of-file-p ()
  (interactive)
  (if (next-line)
      (progn
	(previous-line)
	nil)
    t))

リージョン

リージョンを kill ring に入れる

取り出すには yank を行う.

12345678901234567890 …バッファ先頭にこの文字列があるとする

(kill-region 5 10)
=> t

123451234567890 …kill-region 後はこのようになる.

(yank)
=> 67890
=> t

リージョンで指定した領域を書き換える

文字列の並びを逆にする例.

(defun reverse-string (str)
  (coerce (reverse (coerce str 'list)) 'string))

(defun reverse-string-region ()
  (interactive)
  (save-restriction
    (narrow-to-region (mark) (point))
    (let ((str (buffer-substring (point-min) (point-max))))
      (delete-region (point-min) (point-max))
      (insert (reverse-string str)))))

リージョンの書き換え関数を作るマクロ. 下記でfuncは文字列の引数をひとつ取り,これを書き換える関数.

(defmacro make-region-replace-function (func)
  (let ((str (gensym)))
    `(defun ,(intern (concat (symbol-name func) "-region")) ()
     (interactive)
     (save-restriction
       (narrow-to-region (mark) (point))
       (let ((,str (buffer-substring (point-min) (point-max))))
         (delete-region (point-min) (point-max))
         (insert (,func ,str)))))))
=> make-region-replace-function

(defun rs (str)
  (coerce (reverse (coerce str 'list)) 'string))
=> rs

(make-region-replace-function rs)
=> rs-region

入出力

外部コマンドの実行結果を別バッファを作って取り込む

(defun runcmd (cmd)
  (interactive "sCommand: ")
  (switch-to-buffer "*command*")
  (setq need-not-save t)
  (let (proc)
    (setq proc (make-process cmd))
    (while (eql :run (process-status proc))
      (do-events))))

(runcmd "cmd /c dir c:")

フィルタ系コマンドを作る

カレントバッファにフィルタをかける例.

関数filter-bufferが本体で,引数は以下の2つ. *func: フィルタの評価関数.引数をひとつ取り,これに入力元から一行ずつが与えられる.評価結果が non-nil の場合,その行はフィルタされずに残る. *bufunc: カレントバッファの書き換えでなく,新しくバッファを作りたい場合に切り替えを行う関数.nil ならカレントバッファを書き換える.

(defun filter-buffer (func buffunc)
  "Filter buffer with an evaluation function(func). func must take an argument(a line in a buffer) and return if the line should be left or deleted. If buffunc is non-nil, result is set in a new buffer created by buffunc, otherwise it overwrite the current buffer."
  (let ((s (make-buffer-stream (selected-buffer)))
        (stack nil) line)
    (while (setq line (read-line s nil))
      (if (funcall func line)
          (push line stack)))
    (if buffunc (funcall buffunc))
    (delete-region (point-min) (point-max))
    (insert (format nil "‾{‾A‾%‾}" (reverse stack)))))

;
; utility functions
;
(defun make-tmpbuf (bufname)
  (set-buffer (switch-to-buffer bufname))
  (setq need-not-save t))

;
; sample functions
;
(defun grep-buffer (regexp)
  "Filter buffer with a regular expression. This command edits current buffer directly."
  (interactive "sRegular Expression: ")
  (filter-buffer (lambda (l)
                   (string-match regexp l))
                 (lambda () (make-tmpbuf "*grep*"))))

(defun copy-buffer ()
  (interactive)
  (filter-buffer (lambda (l) t)
                 (lambda () (make-tmpbuf "*copy*"))))

バッファ内の行を一行ずつ処理する

(defun end-line-of-file-p ()
  (interactive)
  (if (next-line)
      (progn
	(previous-line)
	nil)
    t))

(defun foreach-line-buffer (func)
  (interactive)
  (if (eq (buffer-size) 0)
      (message "nil")
    (save-excursion
      (loop
	(let ((bol) (eol))
	  (beginning-of-line)
	  (setq bol (point))
	  (goto-eol)
	  (setq eol (point))
	  (narrow-to-region bol eol)
	  (funcall func bol eol)
	  (widen))
	(next-line)
	(if (end-line-of-file-p)
	    (return)))
      (message "t"))))
⚠️ **GitHub.com Fallback** ⚠️