Tuesday, November 13, 2007

[Emacs Tips] 复制一行

从今天开始打算每天用中文介绍一个 Emacs 小技巧。都是很小的技巧而已。

首先是快速复制一行。基本思想是,光标在哪一行就复制哪一行,不用选定区域。如果区域已经选定了,那么就复制区域。类似于 VIM 的yy。

仍旧使用 M-w 的键绑定,和原先的习惯差不多。使用前提是启用了 transient-mark-mode,即高亮选定区域。实际使用中发现每行开头的空格一点用都没有,而且很碍事,所以今天改了一下,一般从第一个非空格的字符开始复制。

这里提供几个函数。
huangq-save-one-line 是复制一行;如果有参数,则从第一个不是空格的字符开始复制。
huangq-kill-ring-save 如果选定了区域,则复制区域;否则复制行。
huangq-save-line-dwim 如果选定了区域,复制区域;否则从第一个不是空格的字符开始复制。

最后是键绑定:
(global-set-key (kbd "M-w") 'huangq-save-line-dwim)

函数的实现:
;;;###autoload
(defun huangq-save-one-line (&optional arg)
"save one line. If ARG, save one line from first non-white."
(interactive "P")
(save-excursion
(if arg
(progn
(back-to-indentation)
(kill-ring-save (point) (line-end-position)))
(kill-ring-save (line-beginning-position) (line-end-position)))))

;;;###autoload
(defun huangq-kill-ring-save (&optional n)
"If region is active, copy region. Otherwise, copy line."
(interactive "p")
(if (and mark-active transient-mark-mode)
(kill-ring-save (region-beginning) (region-end))
(if (> n 0)
(kill-ring-save (line-beginning-position) (line-end-position n))
(kill-ring-save (line-beginning-position n) (line-end-position)))))

;;;###autoload
(defun huangq-save-line-dwim (&optional arg)
"If region is active, copy region.
If ARG is nil, copy line from first non-white.
If ARG is numeric, copy ARG lines.
If ARG is non-numeric, copy line from beginning of the current line."
(interactive "P")
(if (and mark-active transient-mark-mode)
;; mark-active, save region
(kill-ring-save (region-beginning) (region-end))
(if arg
(if (numberp arg)
;; numeric arg, save ARG lines
(huangq-kill-ring-save arg)
;; other ARG, save current line
(huangq-save-one-line))
;; no ARG, save current line from first non-white
(huangq-save-one-line t))))

No comments: