emacsに寄り道中

vimの操作に慣れつつあり、ふと、前に挫折したemacsもいけるんじゃないかと寄り道してみた。

結果、問題無く使い始められた♪
でもなにか、「yy」での行コピーとか「dd」での行削除は楽だったなーという感が。
やはりどちらにも良いとこ有り悪いとこ有りか。で、それを補うためのカスタマイズということか。

viをエミュレートしたviperモードとかもあるそうだが、自分の欲しいところだけ自分好みにカスタマイズしたかったので、「C-l」をプレフィックスとしてviっぽいキーバインドを持ってきてみた。
(実際のところは lisp によるカスタマイズの勉強のためというところが強いかも。。。)

なんかキーバインドいじってるだけで楽しいな、と。
今は、買ったばかりのおもちゃを触ってるような感覚です。

(define-key global-map "\C-\M-l" 'recenter)
(define-prefix-command 'my-vi-map)
(global-set-key "\C-l" 'my-vi-map)

(define-key my-vi-map " " 'select-whole-line)
(define-key my-vi-map "yy" 'vi-copy-line)
(define-key my-vi-map "yw" 'vi-copy-word)
(define-key my-vi-map "dd" 'vi-kill-line)
(define-key my-vi-map "dw" 'vi-kill-word)
(define-key my-vi-map "o" 'vi-put-line)
(define-key my-vi-map "O" 'vi-put-line-previous)
(define-key my-vi-map "p" 'vi-paste)
(define-key my-vi-map "P" 'vi-paste-previous)

;; 単語の始めかどうか
(defun bowp ()
  (interactive)
  (let (nowp newp)
    (setq nowp (point))
    (forward-word)
    (backward-word)
    (setq newp (point))
    (goto-char nowp)
    (if (eq nowp newp) t nil)))

;; 単語の最後かどうか
(defun eowp ()
  (interactive)
  (let (nowp newp)
    (setq nowp (point))
    (backward-word)
    (forward-word)
    (setq newp (point))
    (goto-char nowp)
    (if (eq nowp newp) t nil)))

;; 単語選択
(defun vi-select-word ()
  (interactive)
  (if (not (bowp)) (backward-word))
  (mark-word))

;; vi 単語コピー
(defun vi-copy-word ()
  (interactive)
  (let (pos)
    (setq pos (current-column))
    (vi-select-word)
    (copy-region-as-kill (point) (mark))
    (move-to-column pos)))

;; 行選択
(defun select-whole-line ()
  (interactive)
  (if (eq mark-active nil)
      (if (eolp)
          (progn (set-mark (point)) (beginning-of-line))
          (progn (beginning-of-line) (set-mark (point)) (end-of-line)))
      (setq mark-active nil)))

;; vi 行切り取り
(defun vi-kill-line ()
   (interactive)
   (select-whole-line)
   (kill-region (point) (mark))
   (delete-backward-char 1))

;; vi 単語切り取り
(defun vi-kill-word ()
  (interactive)
  (vi-select-word)
  (kill-region (point) (mark)))

;; vi 次行改行挿入
(defun vi-put-line ()
  (interactive)
  (end-of-line)
  (newline-and-indent))

;; vi 前行改行挿入
(defun vi-put-line-previous ()
  (interactive)
  (beginning-of-line)
  (newline-and-indent)
  (previous-line))

;; vi 貼り付け
(defun vi-paste ()
  (interactive)
  (if (not (and (bolp) (eolp))) (vi-put-line))
  (yank))

;; vi 前行への貼り付け
(defun vi-paste-previous ()
  (interactive)
  (vi-put-line-previous)
  (yank))