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选择区(不是内容)

参考文档:

 

posted @ 2011-06-04 18:14  巴蛮子  阅读(1144)  评论(1编辑  收藏  举报