Emacs: 小物色々

# Window 分割したとき下側をアクティブに

機能追加拡張しても基本的にデフォルトは大きく壊したくない人なんですが、ウィンドウ分割したときデフォルトで上側がアクティブになるのにだけはどうしても慣れなくて、分割した時点で勝手に下側のウィンドウがアクティブになるようにするものです。

```emacs-lisp:split-window-above.el
(defun split-window-above (&optional size)
  "画面分割したとき下のウィンドウがアクティヴになる."
  (interactive)
  (split-window nil size 'above))
(global-set-key "\C-x2" 'split-window-above)
```

# 時間挿入

ぞれぞれ自分で作ってそうなやつですね。
Mule を使っていた頃は SKK の機能でやっていた気がします。

通常 `current-time-string` の出力がそのまま挿入されます。

プレフィクス付だと `20180428` のようなフォーマットになります。
ファイル名に日付を埋め込みたい場合によく使います。

`C-u C-u C-c t` 等のような複数プレフィクスだと `201804280925` のように時間まで含めますが、こちらはまったく使っていません。

```emacs-lisp:put-times.el
(defun put-times (&optional prefix)
  (interactive "P")
  (insert 
   (cond
    ((not prefix)
     (current-time-string))
    ((equal prefix '(4))
     (format-time-string "%Y%m%d"))
    (t
     (format-time-string "%Y%m%d%H%M")))))
(global-set-key "\C-ct" 'put-times)
```

# ファイルのデュプリケイト

Dired でカーソル位置のファイルをデュプリケートします。
ファイル名にそのときの時間が追加されただけの、まったく同じファイルができます。

>  -rw-rw-rw-     3404 04-28 10:35 komono-201804281035.el
>  -rw-rw-rw-     3404 04-28 10:34 komono.el

ファイル名に既に `20180426` のような時間情報が含まれていれば、その部分を実行した時間に更新して複製します。

細かい時間まで使っていので、即座に複製して名前が衝突する場合はエラーになって複製できません。
少し間を置いて再度実行してください。

リビジョンコントロールするまでもなく、オリジナルを温存したままちょっと試しに書き換えたいとき等によく使います。

```emacs-lisp:dup-file.el
(defcustom dup-filename-date-regexp
  "[12][0-9][0-9][0-9][01][0-9][0-3][0-9]\\([0-9][0-9]\\)*"
  "Replace regexp."
  :type 'regexp
  :group 'files)

(defun dup-filename-date-change (file date)
  "ファイル名と置き換える文字列を渡し、正規表現がファイル名に含まれていれば、その部分を文字列に置き換え、さもなくば文字列を挟んで返す."
  (let ((node (file-name-sans-extension file))
	(ext (file-name-extension file)))
    (if (string-match dup-filename-date-regexp file)
	(replace-regexp-in-string dup-filename-date-regexp date file)
      (concat node "-" date "." ext))))

(defun dup-file (prefix)
  "duplicate file."
  (interactive "P")
  (let* ((file (car (dired-get-marked-files)))
	 (date (format-time-string "%Y%m%d%H%M"))
	 (new-file
	  (if prefix
	      (read-string "File name: " (dup-filename-date-change file date))
	    (dup-filename-date-change file date))))
    (if (string-equal file new-file)
	(message "デュプり先が同じ名前になってデュプれません.")
      (copy-file file new-file))
    (revert-buffer)))

(add-hook 'dired-mode-hook
	  (lambda ()
	    (define-key dired-mode-map "\C-cd" 'dup-file)))
```

# 行の二重化

編集バッファ上のカソールの置かれた行の複製を次の行に作ります。

割とよく使う機能で昔の日本製のエディタには大抵ついていたんですが、Emacs にはなかったので、当初は キーボードマクロのようにキル & ヤンクのコマンドを単純に並べて書いたものを使っていました。

これはその後 lisp が判ってきて書き直したものですが、作ったとき迷って PREFIX 付だとカーソルの上の行を2重化するようになっていますが、そちらは結局まったく使っていません。

```emacs-lisp:dup-line.el
(defun dup-line (&optional prefix)
  "カーソル行の二重化.
PREFIX 在りでひとつ上の行をカーソル位置に二重化."
  (interactive "P")
  (save-excursion
    (when prefix
      (beginning-of-line)
      (forward-line -1))
    (insert
     "\n"
     (buffer-substring
      (progn (beginning-of-line) (point))
      (progn (end-of-line) (point))))))
(global-set-key [f8] 'dup-line)
```

ちなみにかなり後に知ったのですが 
`copy-from-above-command` という似た挙動のものがデフォルトでついていますが、ちょっと違っていました。

# みげも
Ruby はよく判らないこともありコンパイラ版のエンジンを使っているのですが、Ruby で書かれた版とコンパイラで書かれた版のオプションが、何故だか違っていて不都合がありそれを回避する仕掛をしたり、ユーザー辞書を書き換えたとき再起動しないでもすぐに反映されるようにしてあります。

使っている版は以下です。古いかもしれません。
> migemo.el Package-Version: 20160924.741  Version: 1.9.1
> cmigemo - C/Migemo Library 1.3 Driver 


参考のため基本設定も書かれていますが、もし利用する場合は自分の環境に合わせ適宜書き換えてください。

```emacs-lisp:sample.el
;; 基本設定
;; https://www.kaoriya.net/software/cmigemo/
(setq migemo-dictionary
  "c:/emacs-25.1/bin/cmigemo-default-win32/dict/utf-8/migemo-dict")
(setq migemo-command         "c:/emacs-25.1/bin/cmigemo-default-win32/cmigemo.exe")
(setq migemo-options         '("-q" "--emacs"))
(setq migemo-user-dictionary "c:/Users/Documents/.emacs.d/migemo/usrdic")
(setq migemo-coding-system    'utf-8)
(setq migemo-regex-dictionary nil)
(load-library "migemo")

;; c/migemo の user dic option が ruby/migemo と違うので入れ替える
(defun migemo-start-process-pre (fun name buffer program args)
  (setq args (delete "-u" args))
  (setq args (delete migemo-user-dictionary args))
  (setq args (append (list "-s" migemo-user-dictionary) args))
  (funcall fun name buffer program args))
(advice-add 'migemo-start-process :around  'migemo-start-process-pre)

(migemo-init)

;; user 辞書を更新したらすぐに反映させる
(defun migemo-auto-reinit nil
  (if (and (equal (upcase buffer-file-name) (upcase migemo-user-dictionary))
	   (member " *migemo*" (mapcar (function buffer-name) (buffer-list))))
      (migemo-reinit)
    nil))
(add-hook 'after-save-hook 'migemo-auto-reinit)

(defun migemo-reinit nil
  (interactive)
  (migemo-kill)
  (migemo-init))
```

# 動作確認している Emacs のバージョン

> GNU Emacs 25.3.1 (i686-w64-mingw32) of 2017-09-18