- [デフォルトバインドされていることに気づきました(Sat Oct 3 07:34:23 2020)]
- [メニューに関する箇所を更新しました(Sat Sep 12 08:06:58 2020)]
バッファ文字数のカウント
web フォームで文字数が決まっているものがときどきありますが、 たまにしかない場面なので Emacs 上でのカウントのしかたが身に着いていなくて、 その都度ググったり info をひっくり返したりしていました。 でも毎回やっていたんじゃ時間や手間が結構馬鹿になりません。
結局 count-words
というのを使えばカレントバッファの文字数、 もしくはリージョンがあればリージョンの文字数が判るんですが、 キーバインドだけしておいてもまたすぐ忘れるので、メニューに登録しておくことによってすぐ判るようにしました。
(define-key-after global-map [menu-bar tools cwords]
'("Count Words" . count-words)
'spell)
これで Menu
-> Tools
の中の Spell Checking
の下に件のコマンドが登録されます。
文字数カウントについては以上です。
以下はキーやメニュー(初稿からアップデートされています)の拡張の仕方なので興味のある方だけどうぞ。
私用キーマップ
ついでにキーにバインドするなら、マイマップを用意しておくと追加が便利になります。
Emacs の掟で C-c
とアルファベット
1からなるシーケンスはユーザー用に予約解放済みなのでそれを例に説明します。
(define-prefix-command 'priv-map)
(define-key global-map "\C-c" 'priv-map)
priv-map
の箇所はお好きな名前で、上記のようにして個人用プレフィクス・マップを作ってバインドしておくと
(define-key global-map "\C-cw" 'count-words)
などと毎回頭からフルストロークで指定しないでも
(define-key priv-map "w" 'count-words)
などと 1キャラ指定で個人用バインドをシンプルに追加していけて整理管理も楽になります。
ちなみに自分は whch-key-mode を使っていて、バインドを忘れていてもこれがヘルプになるのですが、 入れていないデフォルト状態でもプレフィクスの後に C-h
を押すとバインドの一覧が出るので覚えていると素の Emacs を使う場面等で役に立ちます。
私用メニューマップ
メニューは easy-menu-add-item
を使うと設定も追加もこれだけでできます。標準添付関数ですが init.el
で使うにはロードが必要かもしれません。
(require 'easymenu)
(easy-menu-add-item
global-map
'(menu-bar)
'("Private" ; これがそのままマップのシンボルになる.
["Count Words" count-words]
["imenu" imenu-add-menubar-index]
["Remember" remember]
["Dup Line" dup-line]
["Follow Win" follow-delete-other-windows-and-split]
("TimeClock"
["In" timeclock-in]
["Out" timeclock-out]
["Change" timeclock-change]
["Log" timeclock-visit-timelog])))
こんな感じで初期化なしでいきなりまとめて設定でき、入れ子にすれば階層構造の表現もできるようです。
グローバル・マップとメジャー・モード等の並びの間の追加メニューとしては理想的な位置に出現します。
メニュー名がそのままキーマップの名前(ダミーファンクションキーの名前)になるようなので、
このメニューに後からコマンドを追加したい場合は以下の要領で書くだけでできます。
(easy-menu-add-item global-map '(menu-bar Private) ["テスト" version])
オプションの4番目の引数をつけると位置の指定もでき、そのメニュー項目の上に挿入されます。何も指定しないと最後になります。
(easy-menu-add-item global-map '(menu-bar Private) ["テスト2" version] "TimeClock")
最初の count-words メニュー追加案件は(位置は変わりますが)以下一発でも OK だということです。
(easy-menu-add-item global-map '(menu-bar Tools) '["Count Word" count-words] "Spell Cheking")
メニューへのショートカット
メニューのキーボード・ショートカットがないか調べてみると menu-bar-open
と tmm-menubar (Meta + BackQuart)
の2種をとりあえず発見。
前者はフルキーからいけないぽいので使いやすそうなのは後者。
それに後者はデフォルト・バインドもされていて時々誤操作で開いて何だか判らずそっ閉じしていたもの。
これをしばらく使ってみようと思いましたが、デフォルトだと視認性がイマイチなので which-key
に似せた色付けをしてみました。 ちなみに頭の長い英語のヘルプメッセは変数 tmm-completion-prompt
で変更できるようです。
(add-hook 'completion-list-mode-hook
'(lambda ()
(let ((prompt (if (boundp 'tmm-mid-prompt) tmm-mid-prompt "xxx")))
(font-lock-add-keywords
nil
`((" ---[-0-9A-Za-z(/*+,#)]+\\([ ]?[-0-9A-Za-z(/*+,#)]+\\)*" . 'dired-ignored)
(,(concat
"\\(?1:[0-9A-Za-z%]\\)\\(?2:" prompt
"\\)\\(?3:[-0-9A-Za-z(</*+,.#>)]+\\(?:[ ]?[-0-9A-Za-z(</*+,.#>)]+\\)*\\)")
(1 font-lock-constant-face)
(2 font-lock-doc-face)
(3 font-lock-function-name-face)))))))
dired 等多機能なモードのとき起動すると何気にいいヘルプになりますね。
「私的メニュー追加」に間する初稿
[この項 はeasy-menu-add-item
の項の追記で要らなくなった先に書いてあったメニュー追加記事です。 が、こちらも知っておくとメニュー設定の仕組が見えてきます。]
更なるついでにメニューの追加法です。普段そんなに使わないものや自作マクロ等なら私用メニューを作って詰めこんでおくといいでしょう。これも少々指定が増えますがほぼ同じ要領で追加できます。
(define-prefix-command 'priv-menu-map nil "Private")
(define-key-after global-map [menu-bar private] '("Private" . priv-menu-map))
ブラケットの引数がダミーのファンクションキーで、 (private の箇所はこの名前でなくてもいいのですが判りやすいようにします) そのキーに priv-menu-map
を割り振り Private
というメニュー・ラベルを貼り付けます。ラベルは勿論 日本語
でも大丈夫です。
define-key
ではなく define-key-after
ですが、こちらにしないとメニュー先頭(左端)に追加されてしまいます。23
あとは以下のように随時 priv-menu-map
に割り当てれば メニュー Private の中にコマンドを追加していけます。
(define-key priv-menu-map [imenu] '("Imenu Index" . imenu-add-menubar-index))
(define-key priv-menu-map [dupline] '("Duplicate Line" . dup-line))
オマケ
拙作 の Mew 用の拡張を Mew のメニューに追加 [Menu -> Mew -> Select の中]
(define-key-after ;; "1日以内のメール"
(lookup-key mew-summary-mode-map [menu-bar Mew Select])
[day]
'("Within 1 Day" . mew-indays))
(define-key-after ;; "全文検索"
(lookup-key mew-summary-mode-map [menu-bar Mew Select])
[pic]
'("Full Text Search" . mew-summary-selection-by-search))
関連リンク
count-words-region
他のことを調べていてcount-words-region
として M-=
に標準バインドされていた事に気づきました。
scratch で C-h b
してバインド一覧をとって count
で occur してみると見事にマッチ。
記事を書く前に確認したと思ったんですがそう思い込んでいたようです。お恥かしや。
7 matches for "count" in buffer: *Help*
312:<f3> kmacro-start-macro-or-insert-counter
493:C-x l count-lines-page
557:M-= count-words-region
841:C-c M = count-words
870:C-x C-k C-a kmacro-add-counter
871:C-x C-k C-c kmacro-set-counter
875:C-x C-k TAB kmacro-insert-counter
設定も掘ってみると見事にデフォルトバインドされています。
3 matches for "count" in buffer: bindings.el
753: buffer-display-count buffer-display-time
911:(define-key esc-map "=" 'count-words-region)
1360:(define-key ctl-x-map "l" 'count-lines-page)
デフォルト・バインドされていれば、基本的に Emacs 流の伝統的規則性があって覚えられるので、 メニューに当てておくこともないんですが、 menu にもマッピングされているのか見てみましたが、こちらにはセットされていませんでした。
4 matches in 3 lines for "count" in buffer: menu-bar.el
2078: (count 0))
2081: (setq count (1+ count)))
2083: (> count 1)))