Tuesday, December 30, 2014

Emacs でワードをキャメルケース、スネークケース、スパイナルケースに変換するマイナーモード

とある案件対策用のマイナーモード。

当方も年に一回使うか使わないかのため、誰得感満載ですが。

https://github.com/chiyano/extra-letter-cases.el/blob/master/extra-letter-cases.el

camelize, snakify, spinalize 関数を定義し、 それらをラップして camelize-word, snakify-word, spinalize-word といったインタラクティブな関数を提供します。

当方 el-get を愛用しているため以下 el-get による導入方法です。

init.el に以下を記述して eval または Emacs 再起動など。

(setq el-get-sources
      '((:name extra-letter-cases
               :type git
               :url "https://github.com/chiyano/extra-letter-cases.el.git"
               :after (add-hook 'prog-mode-hook 'extra-letter-cases-minor-mode))))

あとは M-x el-get-install extra-letter-cases で導入できます。 詳しくは el-get のほうを参照いただきたく。

上の設定では prog-mode-hook でフックしているため、 なんらかのソースコードファイルを開くと extra-letter-cases-minor-mode が有効になります。 画面下部のインジケータに excases と表示されるはず。

キーバインドはそれぞれ

  • M-p - camelize-word :カーソル位置の文字列をキャメルケースに置き換え
  • M-[ - snakify-word :スネークケースに置き換え
  • M-{ - spinalize-word :スパイナルケースに

これらを M-uM-lM-c などと連携で使用します。

しかし、せっかく調べた word-at-point や Syntax Table は使わずじまい。

そしてやはり誰得感満載。

Saturday, December 27, 2014

Emacs Syntax Table の変更

丁度 M-uM-lM-c みたく、単語をキャメルケース、スネークケース、スパイナルケースに変換したい案件あり。

まずは単語の抜き出にトライ。

単語の抜き出しは word-at-point を活用できそう。だけど _ とか - が含まれてこない。 それらを単語として解釈してもらうにはどう設定すればいいか。

そこで EmacsWiki: Emacs Syntax Table を斜め読み。

結論、諸々解るも、基底(?)のシンタックステーブルを変更する手法だと術が見つからないため断念。

だけど modify-syntax-entry でカレントバッファのシンタックステーブルを変更できるため、 代わりにこれを prog-mode-hooktext-mode-hook に追加して事なきを得ましたと。

init.el に以下。

(defun my-syntax-table ()
  (modify-syntax-entry ?- "w")
  (modify-syntax-entry ?_ "w"))
(add-hook 'prog-mode-hook 'my-syntax-table)
(add-hook 'text-mode-hook 'my-syntax-table)

新しい挙動に慣れないせいか使いにくくなった気がしなくもないですけど。

以降、 EmacsWiki: Emacs Syntax Table の読みメモ。

Emacs Syntax Table

シンタックステーブルは、ワードごとの前後カーソル移動などに使用される。

シンタックスはバッファごとに異なり、メジャーモードでコントロールされる。

シンタックステーブルは standard syntax table を継承する。

Working with Syntax table

C-h s (describe-syntax) でカレントバッファのシンタックステーブルを参照できる。

シンタックステーブルには、各キャラクタやキャラクタレンジと、シンタックスクラスとの対応がリストされる。

シンタックスクラスは以下のシンボルで識別される。

-   whitespace character        /   character quote character
w   word constituent            $   paired delimiter
_   symbol constituent          '   expression prefix
.   punctuation character       <   comment starter
(   open delimiter character    >   comment ender
)   close delimiter character   !   generic comment delimiter
"   string quote character      |   generic string delimiter
\   escape character            @   inherit from `standard-syntax-table'

カレントシンタックステーブルにおける + のシンタックスを参照するには以下。

(char-to-string (char-syntax ?+))

How to define a new syntax table

シンタックステーブルは make-char-table で定義する。

新しいシンタックステーブルは、通常、基本的なシンタックステーブルを継承し、置き換えることで定義する。

スタンダードシンタックステーブルから設定していくには以下。

(setq my-table (make-syntax-table))

text-mode シンタックステーブルからだと以下。

(setq my-table (make-syntax-table text-mode-syntax-table))

Hacking the syntax table

キャラクタのシンタックスは modify-syntax-entry で変更する。

クォータキャラクタにエクスプレッションプレフィックスクラスをセットする例。(Lisp モードでのデフォルト)

(modify-syntax-entry ?' "'")

ブラケット [] にワードクラスをセットし、デリミタとしての解釈を除去する例。

(modify-syntax-entry ?[ "w")
(modify-syntax-entry ?] "w")

などなど、他にも述べられているが本件ではスルー。

カレントシンタックステーブルを変更し、新しいシンタックステーブルを定義するには以下。 (と記載があるけど、この場合 make-syntax-table は standard-syntax-table を戻すのでは)

(defvar my-wacky-syntax-table
     (let ((table (make-syntax-table)))
       (modify-syntax-entry ?[ "w" table)
       (modify-syntax-entry ?] "w" table)
       table))

text-mode のデフォルトテーブルとして my-wacky-syntax-table を指定できる。

(add-hook 'text-mode-hook (lambda ()
            (set-syntax-table my-wacky-syntax-table)))