選択範囲の単語数、文字数、行数、などをMeadowで数えたい場合があります。Shell経由でwcコマンドに文字列を渡して計算してもらい、結果を受けとって表示する、という方法もあるらしいですが、環境依存になってしまうので却下。
そこでEmacs Lispだけでやる方法を探すと、ありました。出典は失念しましたが、とりあえずコードを。これを.emacsに追加すればいいです。
(defun word-count-region-jp (beg end) ;リージョンを指定して、 M-x my-mojisuu とする。 (interactive "r") ;リージョンの最初と最後の位置が beg と end に入る。 (save-excursion (save-restriction (narrow-to-region beg end) ;編集可能領域をリージョンに制限する。 (let (ch ch-id (ch-count 0)) (goto-char (point-min)) ;バッファの先頭へ (while (not (eobp)) ;バッファの最後でない間、 (setq ch (following-char)) ;現在位置の文字を ch に代入 (setq ch-id (nth 0 (split-char ch))) ;その文字の leading-charcter (if (eq 'japanese-jisx0208 ch-id) ;その文字が JIS x 0208 ならば (setq ch-count (1+ ch-count))) ;カウンタ ch-count に 1 を足す。 (if (eq 'katakana-jisx0201 ch-id) ;その文字が半角仮名でも (setq ch-count (1+ ch-count))) ;カウンタ ch-count に 1 を足す。 (forward-char 1)) ;次の文字へ進む。 (message "文字数は%d" ch-count) ;結果表示。 )))) (defun word-count-region-en (start end) (interactive "r") (save-excursion (save-restriction (let ((c 0) (l 0) (w 0) (in-word nil) c-after) (goto-char start) (while (< (point) end) (setq c-after (char-after (point))) ; no need (point) if emacs 20 (if (= c-after ?\n) (setq l (1+ l))) (if (or (= c-after ?\n) (= c-after ? ) (= c-after ?\C-i)) (if in-word (setq w (1+ w) in-word nil)) (setq c (1+ c) in-word t)) (forward-char)) (message (format "%d lines, %d words, %d characters" l w c))))))
これで、「word-count-region-jp」と「word-count-region-en」という関数が定義されます。「word-count-region-jp」の方は文字数だけ、「word-count-region-えn」は文字数、行数、単語数が表示されます。
僕は、このふたつの関数にショートカット「Ctrl+x Ctrl+j」と「Ctrl+x Ctrl+e」を割り当ててます。こんな感じ。
(global-set-key "\C-x\C-e" 'word-count-region-en) (global-set-key "\C-x\C-j" 'word-count-region-jp)
便利便利。