Emacs里的第二选区(secondary selection)
才开始用Emacs时试了一下按住Ctrl/Alt时的鼠标各个键的功能,觉得一团乱麻,没找到规律,好像一不小心把某块文字选中了之后就一直处于反白状态了,取消不了。直到前两天才知道,那是Emacs提供的一个功能: secondary selection,它允许你按住Meta键用鼠标选择第二个块,相当于你有了第二个剪贴板。
具体选择方法跟普通选择(即primary selection)的方法类似,但多了一个Meta键:
- (按住Meta键) 左键选择开始点,右键选择结束点,
- 或者: (按住Meta键) 左键拖选
- 或者: (按住Meta键) 双击、三击左键(选择单词、整行)
选完就行了,它会放到一个内置的剪贴板去(不需单独的拷贝。如果是X下,会放到X的secondary剪贴板)。
选定后如果再次(按住Meta)点击右键,则选中内容被剪切。
粘贴也是用中键,但需要按住Meta。
这个secondary selection会一直显示为被选中状态,直到再用Meta+点击才会消失。
注意这个功能只能在X或者Windows下的GUI界面中使用(Mac我不了解),终端(console和term)下面没有。
用途1: 替换
如果from-string 和 to-string 都是当前buffer已有的内容,则可将它们分别放到primary selection和secondary中,然后在M-%的提示符里面分别用mouse-2、M-mouse-2粘贴。
用途2: 交换两块选中区域的内容
这是我看见这个功能时意识到的一个功能,但在emacswiki的代码中没有找到实现了这个功能的(有个second-sel.el里面提供了一个secondary-swap-region
命令,但试用之后才发现它的作用是将primary选中区变为secondary,将secondary变为primary,而不是交换内容);而且我对于emacs自带的transpose-word/transpose-sexp很不满意,"to my"居然会变成"myto ".
于是我自己写了一个:
(defun transpose-selections () "Transpose the content of the primary region and of the secondary." (interactive) (let ( (osecondary (x-get-selection 'SECONDARY)) ) (unless (and osecondary (overlayp mouse-secondary-overlay)) (error "No secondary selection")) (unless (eq (current-buffer) (overlay-buffer mouse-secondary-overlay)) (error "Primary selection and secondary selection should be in same buffer.")) (let* ( (pri-start (region-beginning)) (pri-end (region-end)) (pri-content (buffer-substring pri-start pri-end)) (sec-start (overlay-start mouse-secondary-overlay)) (sec-end (overlay-end mouse-secondary-overlay)) (sec-content (buffer-substring sec-start sec-end)) ) ;;(message "swap `%s' with `%s'." pri-content sec-content) ;;FIXME: ugly code. any good idea? (if (> sec-start pri-start) (progn ;; move primary's content to secondary's location (delete-region sec-start sec-end) (goto-char sec-start) (insert-string pri-content) ;; move secondary's to primary (delete-region pri-start pri-end) (goto-char pri-start) (insert-string sec-content)) (progn ;; move secondary's to primary (delete-region pri-start pri-end) (goto-char pri-start) (insert-string sec-content)) ;; move primary's content to secondary's location (delete-region sec-start sec-end) (goto-char sec-start) (insert-string pri-content) )))) ;; swap the primay and secondary region (global-set-key (kbd "C-x t") 'transpose-selections)
用法很直观: 用左键拖选普通选区,用M-左键拖选第二选区,然后按C-x t,则两部分内容则会被交换。
补充说明一下上面提到的EmacsWiki上的second-sel.el
相对普通选区,这个secondary selection有两个严重的缺陷
- 没有历史记录,不能象普通kill-ring那样翻阅、使用历史项目;
- 只能鼠标操作,不能键盘操作
这个second-sel.el包主要解决这两个问题。
另外它还有其它几个功能
- isearch里面提供快捷键粘贴secondary selection,没有键盘操作
- 交换primary和secondary选择区(不是内容)
参考文档: