| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2291 人关注过本帖
标题:【本人原创】Emacs的rect-mark.el脚本的一个增强(这个好像没在这发过)
只看楼主 加入收藏
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
结帖率:100%
收藏
 问题点数:0 回复次数:17 
【本人原创】Emacs的rect-mark.el脚本的一个增强(这个好像没在这发过)
;; **************************************************************************************************************
;; By zklhp
;; Email:zklhp@
;; QQ:493165744
;; 2012.4.30
;; 转载请保持完整
;; **************************************************************************************************************

感觉起题目的水平下降了 Emacs用了没几天 第一次发这种东西 不当处望方家指正~

rect- mark.el是个常用的脚本 用于增强Emacs的矩形操作(Rectangle 咋翻译啊 我就管这个叫矩形操作得了 如果你不明白可以试试Word里的Alt+鼠标拖拽 就是这个意思 某些时候这个叫列模式 Column Mode 我感觉这都是指的一个东西) 可以在这里得到

http://www.

这个脚本很不错 我一直用 不过里面的一个功能和我的习惯不一样

218行的 rm-mouse-drag-region 拖动鼠标选择一个矩形块 一般我们的操作习惯是 拖动区域的时候能自动卷屏(Scroll) 但这个脚本不这样 貌似还报个错

代码如下

(defun rm-mouse-drag-region (start-event)
  "Highlight a rectangular region of text as the the mouse is dragged over it.
This must be bound to a button-down mouse event."
  (interactive "e")
  (let* ((start-posn (event-start start-event))
     (start-point (posn-point start-posn))
     (start-window (posn-window start-posn))
     (start-frame (window-frame start-window))
     (bounds (window-edges start-window))
     (top (nth 1 bounds))
     (bottom (if (window-minibuffer-p start-window)
             (nth 3 bounds)
           ;; Don't count the mode line.
           (1- (nth 3 bounds))))
     (click-count (1- (event-click-count start-event))))
    (setq mouse-selection-click-count click-count)
    (mouse-set-point start-event)
    (rm-activate-mark)
    (let (end-event
      end-posn
      end-point
      end-window)
      (track-mouse
    (while (progn
         (setq end-event (read-event)
               end-posn (event-end end-event)
               end-point (posn-point end-posn)
               end-window (posn-window end-posn))
         (or (mouse-movement-p end-event)
             (eq (car-safe end-event) 'switch-frame)))
      (cond
       ;; Ignore switch-frame events.
       ((eq (car-safe end-event) 'switch-frame)
        nil)
       ;; Are we moving within the original window?
       ((and (eq end-window start-window)
         (integer-or-marker-p end-point))
        (goto-char end-point)
        (rm-highlight-rectangle start-point end-point))
       ;; Are we moving on a different window on the same frame?
       ((and (windowp end-window)
         (eq (window-frame end-window) start-frame))
        (let ((mouse-row (+ (nth 1 (window-edges end-window))
                (cdr (posn-col-row end-posn)))))
          (cond
           ((< mouse-row top)
        (mouse-scroll-subr (- mouse-row top)
                   nil start-point))
           ((and (not (eobp))
             (>= mouse-row bottom))
        (mouse-scroll-subr (1+ (- mouse-row bottom))
                   nil start-point)))))
       (t
        (let ((mouse-y (cdr (cdr (mouse-position))))
          (menu-bar-lines (or (cdr (assq 'menu-bar-lines
                         (frame-parameters)))
                      0)))
          ;; Are we on the menu bar?
          (and (integerp mouse-y) (< mouse-y menu-bar-lines)
           (mouse-scroll-subr (- mouse-y menu-bar-lines)
                      nil start-point)))))))
      (and (eq (get (event-basic-type end-event) 'event-kind) 'mouse-click)
       (eq end-window start-window)
       (numberp end-point)
       (if (= start-point end-point)
           (setq deactivate-mark t)
         (push-mark start-point t t)
         (goto-char end-point)
         (rm-kill-ring-save start-point end-point)))
      )))

elisp学过皮毛 我感觉 这里猫腻出在 mouse-scroll-subr 也就是下面三句

(mouse-scroll-subr (- mouse-row top) nil start-point)
(mouse-scroll-subr (- mouse-y menu-bar-lines) nil start-point)
(mouse-scroll-subr (1+ (- mouse-row bottom)) nil start-point)

因为只有这里跟卷屏有关 那这个函数咋用呢

在我的Emacs 24里(GNU Emacs是本文的环境 其他的没试) C-h f 呵呵 也就是看函数描述 结果如下

mouse-scroll-subr is a compiled Lisp function in `mouse.el'.

(mouse-scroll-subr WINDOW JUMP &optional OVERLAY START)

Scroll the window WINDOW, JUMP lines at a time, until new input arrives.
If OVERLAY is an overlay, let it stretch from START to the far edge of
the newly visible text.
Upon exit, point is at the far edge of the newly visible text.

第一个参数是WINDOW(写中文有可能有误会 关于这个欢迎看Emacs的Tutorial) 而这里没写

我猜测这里是个bug 可能作者写这个脚本的年代这个函数和现在不一样罢(95年的脚本了 和一样都是90后诶 不过90后比较年轻90后的代码就很老了。。) Emacs的版本更新了但脚本没有做到与时俱进 导致了bug

改正方法 我的改法是加个参数 变成这样

(mouse-scroll-subr start-window (- mouse-row top) nil start-point)
(mouse-scroll-subr start-window (- mouse-y menu-bar-lines) nil start-point)
(mouse-scroll-subr start-window (1+ (- mouse-row bottom)) nil start-point)

由于我们拖动的时候一般只在一个Window里 所以我默认和开始的是一样的 把上面三个分别替换成我上面写的语句 这个脚本的行为就和我们的预期一样了

改后的代码再帖一下

;;;###autoload
(defun rm-mouse-drag-region (start-event)
  "Highlight a rectangular region of text as the the mouse is dragged over it.
This must be bound to a button-down mouse event."
  (interactive "e")
  (let* ((start-posn (event-start start-event))
     (start-point (posn-point start-posn))
     (start-window (posn-window start-posn))
     (start-frame (window-frame start-window))
     (bounds (window-edges start-window))
     (top (nth 1 bounds))
     (bottom (if (window-minibuffer-p start-window)
             (nth 3 bounds)
           ;; Don't count the mode line.
           (1- (nth 3 bounds))))
     (click-count (1- (event-click-count start-event))))
    (setq mouse-selection-click-count click-count)
    (mouse-set-point start-event)
    (rm-activate-mark)
    (let (end-event
      end-posn
      end-point
      end-window)
      (track-mouse
    (while (progn
         (setq end-event (read-event)
               end-posn (event-end end-event)
               end-point (posn-point end-posn)
               end-window (posn-window end-posn))
         (or (mouse-movement-p end-event)
             (eq (car-safe end-event) 'switch-frame)))
      (cond
       ;; Ignore switch-frame events.
       ((eq (car-safe end-event) 'switch-frame)
        nil)
       ;; Are we moving within the original window?
       ((and (eq end-window start-window)
         (integer-or-marker-p end-point))
        (goto-char end-point)
        (rm-highlight-rectangle start-point end-point))
       ;; Are we moving on a different window on the same frame?
       ((and (windowp end-window)
         (eq (window-frame end-window) start-frame))
        (let ((mouse-row (+ (nth 1 (window-edges end-window))
                (cdr (posn-col-row end-posn)))))
          (cond
           ((< mouse-row top)
            ;; patched here! Use start-window as the first parameter.
        (mouse-scroll-subr start-window (- mouse-row top)
                   nil start-point))
           ((and (not (eobp))
             (>= mouse-row bottom))
            ;; patched here! Use start-window as the first parameter.
        (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
                   nil start-point)))))
       (t
        (let ((mouse-y (cdr (cdr (mouse-position))))
          (menu-bar-lines (or (cdr (assq 'menu-bar-lines
                         (frame-parameters)))
                      0)))
          ;; Are we on the menu bar?
          (and (integerp mouse-y) (< mouse-y menu-bar-lines)
               ;; patched here! Use start-window as the first parameter.
           (mouse-scroll-subr start-window (- mouse-y menu-bar-lines)
                      nil start-point)))))))
      (and (eq (get (event-basic-type end-event) 'event-kind) 'mouse-click)
       (eq end-window start-window)
       (numberp end-point)
       (if (= start-point end-point)
           (setq deactivate-mark t)
         (push-mark start-point t t)
         (goto-char end-point)
         (rm-kill-ring-save start-point end-point)))
      )))

习惯了 必须总结一下

1 Emacs真是历史悠久(随便一个脚本都和我差不多大)扩展性强(本身不具备的功能可以用elisp扩充)的神的编辑器啊!!!

2 历史悠久 带来的历史问题也就比较突出了 比如Ctrl键位 比如上面的Window 比如这个脚本

3 通过脚本扩展功能是开源软件的优点 类似的例子是Firefox 这些软件具有无限的扩展性 但扩展带来的问题可能比软件本身大

4 接上面 由于扩展尤其是脚本类的扩展是直接给出代码的 新手也可以比较容易的修改 总的来说利大于弊 特别是对于喜欢自己动手的人来说

5 貌似没人发现这个问题 反正我找的时候没发现有人提 为啥啊 可能这个是比较偏的功能罢


[ 本帖最后由 zklhp 于 2012-9-7 21:29 编辑 ]
搜索更多相关主题的帖子: Email 
2012-09-07 21:24
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
有权利真是好啊 怪不得有人老骂【权限狗】啊

自己顶了 我看了下貌似没再我们论坛发过

本来发在百度空间的 不过自从空间改版 空间就…… 所以想想还是移动到这里罢
2012-09-07 21:28
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
好东西啊
有人说emacs是种生活态度 。。。

梅尚程荀
马谭杨奚







                                                       
2012-09-07 22:04
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
捧场。
2012-09-07 22:53
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
以下是引用有容就大在2012-9-7 22:04:48的发言:

好东西啊
有人说emacs是种生活态度 。。。

这是真的。因为只要愿意,几乎能在 emacs 里干所有的事。
2012-09-07 23:04
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
回复 5楼 pangding
期待学会这东西

梅尚程荀
马谭杨奚







                                                       
2012-09-07 23:57
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
我个人不大喜欢这种All in one 的做法 不过现在编程和文本处理我都用emacs了 我的本科论文和现在写的其他中英文论文都是emacs录入的
2012-09-08 09:37
madfrogme
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:21
帖 子:1160
专家分:1106
注 册:2009-6-24
收藏
得分:0 
能不能简单解释一下矩行操作是什么吗

The quieter you become, the more you can hear
2012-09-08 10:28
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
以下是引用madfrogme在2012-9-8 10:28:37的发言:

能不能简单解释一下矩行操作是什么吗

图片附件: 游客没有浏览图片的权限,请 登录注册


我觉得大概就是这个东西 VS里面也有
2012-09-08 10:38
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
回复 9楼 zklhp
第一次见啊

梅尚程荀
马谭杨奚







                                                       
2012-09-08 10:43
快速回复:【本人原创】Emacs的rect-mark.el脚本的一个增强(这个好像没在这发过)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.059003 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved