transient-mark-mode と comment-dwim とボク

序章

どうやら,プロは,transient-mark-mode を nil にしておくらしい。
たしかにそうすれば,C-SPC で mark をガシガシ push できる。
で,こないだ,transient-mark-mode を nil にしていたのが,
このお話のはじまり。

問題発生!!

transient-mark-mode が nil だと,M-; でできていた comment-region,
uncomment-region ができなくたってしまったのだ。


こいつは,困った。
調べると,M-; は,comment-dwim にバインドされている。
んで,commenmt-dwim は,transient-mark-mode が,non-nil の時には,
comment-or-uncomment-region 関数を呼んでいる。
で,comment-or-uncomment-region 関数は,リージョンの内容によって,
comment-region か,uncomment-region を呼んでいる。
そして,これらをボクが呼んでいる。
そう思った5月の暑い日。

奮起

だが,ボクはあきらめない。
なんたって,Emacs Lisp Intro を読んでいるからだ。
そして,考えることしばし。
「M-; をタイプしたときに,transient-mark-mode を non-nil にして,
comment-dwim を呼べばいいんだ。」

こんな感じか。

(defun my-comment-dwim ()
  ""
  (interactive)
  (setq transient-mark-mode t)
  (comment-dwim)
  (setq transient-mark-mode nil))


だが,wrong number of arguments と怒られる。
そこで,comment-dwim のソースを見てみる。
(newcomment.el から一部抜粋,コメント部分を削除)

(defun comment-dwim (arg)
  (interactive "*P")
  (comment-normalize-vars)
  (if (and mark-active transient-mark-mode)
      (comment-or-uncomment-region (region-beginning) (region-end) arg)


いっけね,引数が必要なんだ。
そのために,(interactive "*P") してるのか。
あっ! しかも,さっきのだと,my-comment-dwim を呼ぶ前に,
transient-mark-mode が non-nil の時は,その値を変更しちゃってる。
いっけね。


こんなときに使えるのは・・・。
!! let 君!!
よし,今度こそ。

(defun my-comment-dwim (arg)
  "Just call comment-dwim with transient-mark-mode enabled."
  (interactive "*P")
  (let ((transient-mark-mode t))
    (comment-dwim arg)))


うん,うまくいったぞ。
さっそくキーバインドを変更だ。
(global-set-key "\M-;" 'my-comment-dwim)

奥に潜むやつ

ぬあぁー!!
それは,text-mode で,文章を書いていたときに起こった。
コメント用の文字が決まっていないと,M-; したときに,
何を使うか聞かれる。その間は,transient-mark-mode が有効になっているので,
リージョンに色が付いてしまう!!

妥協

人生,妥協が大事だ,みたいなのをどっかで見たことがある。
よし,この件については,この辺で妥協しておこう。

まとめ

どんなオチやねん!


また駄文を生み出してしまった。。。
とりあえずの完成品をば。

;; transient-mark-mode が nil だと,M-; で,
;; comment-region が呼ばれないようなので,
;; 一時的に,transient-mark-mode を有効にして,
;; comment-dwim を呼ぶ。
(defun my-comment-dwim (arg)
  "Just call comment-dwim with transient-mark-mode enabled."
  (interactive "*P")
  (let ((transient-mark-mode t))
    (comment-dwim arg)))
;; M-; に上書きしておく
(global-set-key "\M-;" 'my-comment-dwim)

課題

要は,最初にコメント用の文字が決まっているかどうか調べる。
決まっていたら,transient-mark-mode を有効にして,
comment-dwim。
決まってなかったら,入力を取得してから,
transient-mark-mode を有効にして,
comment-dwim。
こんな感じで書けばいけそうだけど,調べるのめんどくせーし,
とても眠いので,勇者が現れるのを待つことにする。