括弧をまとめて挿入

自分は, bracket.el というものを使って,
括弧類, (), [], "", '', {} は, 対応するものもまとめて, 挿入するようにしている.
例えば, 動作としては, 「(」を押したら, 「)」も自動で挿入するような感じ.
それで, 今日思いたって, マークが指定されていたら, その範囲を括弧でくくるように改造してみた.



以下ソース. 関数のみ. かなりやっつけで改造.

(defun insert-braces (arg &optional open close)
  "A pair of brace is insert automatically."
  (interactive "p")
  (if mark-active
     (save-excursion
       (let (start end)
         (if (> (point) (mark))
             (setq start (mark) end (point))
           (setq start (point) end (mark)))
         (goto-char start)
         (insert (or open "{"))
         (goto-char (+ end 1))
         (insert (or close "}"))))
    (if (and open close)
        (insert (format "%s%s" open close))
      (insert "{}"))
    (backward-char 1)))
(defun insert-brackets (arg)
  "A pair of square bracket is insert automatically."
  (interactive "p")
  (insert-braces arg "[" "]"))
(defun insert-parens (arg)
  "A pair of round bracket is insert automatically."
  (interactive "p")
  (insert-braces arg "(" ")"))
(defun insert-single-quotation (arg)
  "A pair of single quotation is insert automatically"
  (interactive "p")
  (insert-braces arg "'" "'"))
(defun insert-double-quotation (arg)
  "A pair of double quatation is insert automatically."
  (interactive "p")
  (insert-braces arg "\"" "\""))

もうちょっと上手くならなかったかなあ, point と mark の部分なんか特に.

追記

plus さんによる最適化版?改造版?をここに載せておきます.
変数 my-brace-type-alist で関数の追加ができるようになっており, より柔軟になっています.
single-quotation が, 自分の環境だと, ' を \' のようにクォートしないと上手く動かなかったので,
そのように変更してあります.

(*追記*)私の勘違いでした. すいません. m(_ _)m

(defvar my-brace-type-alist
 '(("braces" "{" "}")
   ("brackets" "[" "]")
   ("parens" "(" ")")
   ("single-quotation" "'" "'")
   ("double-quotation" "\"" "\"")))

(mapc
 (lambda (x)
  (fset (intern (concat "insert-" (car x)))
        #'(lambda ()
            (interactive)
            (let* ((func-name (replace-regexp-in-string
                               "insert-" "" (symbol-name this-command)))
                   (type (assoc func-name my-brace-type-alist))
                   (open (cadr type))
                   (close (caddr type)))
              (save-restriction
                (if mark-active
                    (narrow-to-region (region-beginning) (region-end))
                  (narrow-to-region (point) (point)))
                (goto-char (point-min))
                (insert open)
                (goto-char (point-max))
                (insert close))
              (backward-char 1)))))
 my-brace-type-alist)

SKK を使ってるともしかしたら相性がよくないかもしれません.
アルファベットを入力するときは大丈夫ですが, 日本語入力のときにエラーが出てしまうようです.
# this-command の部分が肝なんだなあ. コードからコードの関数名を取れないものか.


ついでに, SKK での「」の挿入もリージョンが指定されていたら,
リージョンを括るように「」を挿入するようにした.
その部分だけ抜き出すのが面倒なので, SKK でルールを追加してる部分を全部書いてみる.
まあ, あれだ, ネット上にバックアップを残しとくみたいな意味も込めてさw

(defun my-skk-insert-brace (arg)
  "「を押したら, 」も挿入する.
リージョンが指定されていたならば, その範囲を「」で括る."
  (if mark-active
     (save-excursion
       (let (start end)
         (if (> (point) (mark))
             (setq start (mark) end (point))
           (setq start (point) end (mark)))
         (goto-char start)
         (insert "「")
         (goto-char (+ end 1))
         (insert "」")))
      (insert "「」")
    (backward-char 1)))

;; skkのかな入力時, 独自の規則を追加.
(setq skk-rom-kana-rule-list
      (append skk-rom-kana-rule-list
              '(("h," nil ("、" . "、"))
                ("h." nil ("。" . "。"))
                ("h/" nil ("/"  . "/" ))
                ("z=" nil ("≠" . "≠"))
                ("z(" nil "【")
                ("z)" nil "】")
                ("z{" nil "〔")
                ("z}" nil "〕")
                ("["  nil my-skk-insert-brace)
                ;; http://www.unixuser.org/~ysjj/emacs/lisp/skk-init.el より拝借.
                ;; 何故か半角になっちゃう.
                ;; どうも utf-8 で書いてたのが原因だった模様.
                ("zga" nil ("α" . "α")) ("zGa" nil ("Α" . "Α"))
                ("zgb" nil ("β" . "β")) ("zGb" nil ("Β" . "Β"))
                ("zgc" nil ("ψ" . "ψ")) ("zGc" nil ("Ψ" . "Ψ"))
                ("zgd" nil ("δ" . "δ")) ("zGd" nil ("Δ" . "Δ"))
                ("zge" nil ("ε" . "ε")) ("zGe" nil ("Ε" . "Ε"))
                ("zgf" nil ("φ" . "φ")) ("zGf" nil ("Φ" . "Φ"))
                ("zgg" nil ("γ" . "γ")) ("zGg" nil ("Γ" . "Γ"))
                ("zgh" nil ("η" . "η")) ("zGh" nil ("Η" . "Η"))
                ("zgi" nil ("ι" . "ι")) ("zGi" nil ("Ι" . "Ι"))
                ("zgj" nil ("ξ" . "ξ")) ("zGj" nil ("Ξ" . "Ξ"))
                ("zgk" nil ("κ" . "κ")) ("zGk" nil ("Κ" . "Κ"))
                ("zgl" nil ("λ" . "λ")) ("zGl" nil ("Λ" . "Λ"))
                ("zgm" nil ("μ" . "μ")) ("zGm" nil ("Μ" . "Μ"))
                ("zgn" nil ("ν" . "ν")) ("zGn" nil ("Ν" . "Ν"))
                ("zgo" nil ("ο" . "ο")) ("zGo" nil ("Ο" . "Ο"))
                ("zgp" nil ("π" . "π")) ("zGp" nil ("Π" . "Π"))
                ("zgq" nil ("・" . "・")) ("zGq" nil ("−" . "−"))
                ("zgr" nil ("ρ" . "ρ")) ("zGr" nil ("Ρ" . "Ρ"))
                ("zgs" nil ("σ" . "σ")) ("zGs" nil ("Σ" . "Σ"))
                ("zgt" nil ("τ" . "τ")) ("zGt" nil ("Τ" . "Τ"))
                ("zgu" nil ("θ" . "θ")) ("zGu" nil ("Θ" . "Θ"))
                ("zgv" nil ("ω" . "ω")) ("zGv" nil ("Ω" . "Ω"))
                ("zgw" nil ("σ" . "σ")) ("zGw" nil ("Σ" . "Σ"))
                ("zgx" nil ("χ" . "χ")) ("zGy" nil ("Υ" . "Υ"))
                ("zgy" nil ("υ" . "υ")) ("zGx" nil ("Χ" . "Χ"))
                ("zgz" nil ("ζ" . "ζ")) ("zGz" nil ("Ζ" . "Ζ")))))
;; ルールを更新
(setq skk-rule-tree
      (skk-compile-rule-list
       skk-rom-kana-base-rule-list skk-rom-kana-rule-list))

上記ソースの中の ("[" nil my-skk-insert-brace) の部分がそう.
SKK は, 引数を1つだけ取る関数をローマ字変換の規則(といったらいいのかな?)に割り当てて動作させることができる.
取った引数をどのように使ってるのかはよく知らない.



思いたって, やってみたけど, まあ, 意外と便利.
やっぱり思いたったら行動してみるもんやなあ. こんな些細なことでも.

更新時刻

  • 1かいめ 2007年, 8月14日, 1:16
  • 3かいめ 2007年, 8月16日, 1:26