2012年12月8日星期六

终端下使用Emacs的一些Tips

这里说的终端,其实主要是指终端模拟器,也即putty/mintty, xshell, gnome-terminal, xfce4-terminal等。虽然说理论上来说,大多数内容也适用于控制台,但我并没有在上面验证过。

* 多frame

如果你像我一样用Frame Bufs这个扩展将不同“工程”的buffer组织在不同的frame上,那么肯定也想问终端下是否支持frame,答案是肯定的。仍然使用C-x 5 2来创建新的frame, 用C-x 5 o切换frame。与GUI下的差别是你不能调整frame的大小了,因为一致都是全屏——如果你想要用半个终端来跑别的东西,建议用tmux或者 Emacs里面的ansi-term-mode.

参考: Emacs Journey: CLI Emacs and multiple-frames

* 鼠标

除了终端模拟器自己的拷贝、粘贴和右键菜单,终端模拟器里面跑的应用程序其实也是可以使用鼠标的,这些终端模拟器大都支持一种叫做Xterm mouse tracking的功能: 终端模拟器收到鼠标时,先看看是不是应该用来应对自己的功能(比如文字拷贝、粘贴和右键菜单),如果不是,则将按键信息通过Xterm control sequences将按键信息发送给应用程序。

GNU Emacs可以通过M-x xterm-mouse-mode打开终端下的鼠标功能。

不过有几点值得注意:

  • 所用的Emacs必须编译进了鼠标支持才能使用xterm-mouse-mode。一般来说,如果你安装的Emacs是带X11版本的,那么就没有问题;如果你安装的是emacs-nox,那么就不支持鼠标了。
    (其实这个说法并不严谨,但根据Emacs的缺省编译设置,的确是在有window-system的时候才打开HAVE_MOUSE这个定义,configure脚本没有单独对鼠标支持提供开关。而最近的一个HAVE_MOUSE补丁则完全放开了鼠标支持,你可以在老版本Emacs代码上打上这个补丁重新编译)
  • 如果你想为鼠标事件增加Ctrl,Alt和Shift修饰键(modifier)的支持,比如绑定<S-mouse-1>或者<M-mouse-3>到某个事件,虽然理论上是支持的,但实际上都比较悲摧,自己用C-h k试试就知道了(唯一比较幸运一点的是Ctrl)
  • 鼠标滚轮可以用。不过跟GUI下不同的是,几乎没有带修饰键的版本可用(也就是说不能绑定<C-mouse-4>, <M-mouse-4>这些事件 (P.S. 在Linux系统上,鼠标滚轮事件名叫<mouse-4>和<mouse-5>,跟Windows下的<wheel-up>和<wheel-down>并不一样(不清楚Mac OS X等系统))
  • 终端模拟器都有一些自己鼠标功能(比如选择文本拷贝到本地剪贴板,显示右键菜单),可能会保留Ctrl/Alt/Shift中的某一个用来做这方面的用途
    这个设置在Putty里面是Configuration->Window->Selection->Shift overrides application's use of mouse; 在Mintty里则是 Configuration->Mouse->Modifier key for overriding default ; 而Gnome Terminal里则不提供配置,右键(<mouse-3>)始终被自己接管,按住Shift始终是本地的选择文字功能,里面跑的应用程序永远无法得到这两个事件


* 颜色

如果你用终端模拟器(gnome-terminal,guake, putty或者mintty)来运行emacs, 其实它们也是支持256色的。这样你的语法高亮配色就有了更多选择。

如果你的UNIX比较新,terminfo里面有xterm-256color 这个类型的终端描述的话,只要先执行如下语句:
export TERM=xterm-256color

然后再启动emacs,那么emacs就有了256色了, 用M-x list-colors-display看看列出了多少颜色就知道生效与否了。

** 终端模拟器支持

putty缺省是支持256色的,只要你没有在选项Window->Colours里面关闭Allow terminal to use xterm 256-color mode这一项。那么用上面的TERM环境变量就够了。

mintty里面,你可以直接在Options->Terminal->Type里面选择xterm-256color,这样进去之后shell就会继承这个设置,不用手工设置TERM环境变量了——当然你在交互式方式或者~/.bashrc里面设置也行,不过这本来就应该是终端模拟器端的设置。

另外,如果你又在终端模拟器(gnome-terminal, putty)里面跑了screen/tmux的话,那么得启动screen/tmux之前把TERM设置成256色模式(xterm-256color或者rxvt-256color之类),然后在screen/tmux的window中把TERM设置为screen-256color,详细内容请参看ArchWiki: Tmux: Set the correct TERM

一些文章上说,只要在tmux里面启动一个window后,在里面执行export TERM=screen-256color(或者在~/.tmux.conf里面添加set -g default-terminal "screen-256color" 来自动设置)。但根据我的试验,启动tmux之前不设置TERM是实际上得不到256种不同颜色的

** terminfo问题

如果用的Linux比较老,terminfo数据库里没有xterm-256color或者screen-256color这个类型的定义(用ls /lib/terminfo/s/可以列举所有以s开头的terminal type),那么你就没法用这个功能了(FIXME: 怎么加上这个类型定义?)

实测是否真支持256色(而不是名义上有256色却有很多重复的颜色)的一个方法是用这篇The 256 color of xterm里面提供的perl脚本256colors2.pl,它会显示类似如下的图:

xterm 256 color test

 

* 待续

  • 快捷键(key bindings)
  • Emacs菜单问题 (lacarte)
  • Emacs overlay和fringe (auto-complete, hideshow-fringe, qtmstr-outline etc)

 

 

本文链接



(automatically copied by ifttt from http://www.cnblogs.com/bamanzi/archive/2012/12/08/tips-about-emacs-on-term.html)

Emacs 24.3支持cygwin上使用Win32 GUI

刚看见GNU Emacs 24.3发了第一个pretest版本(24.2.90),我从git仓库里打开NEWS看了一下,发现了这么一条:


  ** Cygwin builds can use the native MS Windows user interface.  Pass --with-w32 to configure. The default remains the X11 interface.


哈,这正是我原来一直梦想着的特性:底层采用Cygwin的POSIX兼容层,界面采用Win32原生GUI——这在以前看到rxvt的win32原生GUI版本时就有了这个愿望。

这样有什么好处呢?

1 底层采用Cygwin的POSIX兼容层

  • Emacs与shell和其它程序的交互就跟UNIX下面一样了,这样很多win32特有的兼容性问题就不存在了,比如调用一个shell命令时的引号问题(比如悲摧的find-grep,比如M-x shell-toggle-cd里面的"cd /path/to/somewhere""cd /d x:\path\to\somewhere"问题);反过来,你在git/hg里面可以很方便地调用ediff和emerge来比较文件、解决合并冲突了
  • cygwin有虚拟终端支持,这样你可以用M-x term来运行各类终端程序,比如bpython, midnight commander。反过来,如果用cygwin版本的Emacs,你也可以在screen里面跑emacs

2. GUI采用win32 gui

  • 相对terminal版本,GUI的优势是有丰富的颜色、字体以及fringe修饰
  • 相对原来的X11 GUI版本,优势是不必启动一个X11 server了
  • 这个cygwin-w32版本有win32 native版本的几乎所有功能
    • 可以从Windows程序(比如资源管理器)拖放文件到Emacs
    • 可以使用Windows所管理的字体,也就是你不用自己再安装配置X11字体
    • 可以使用<lwindow>, <rwindow>, <apps>等键,也就是说w32-lwindow-modifier等变量仍然可以设置
    • 缺省打开浏览器的方法与win32 native版本和cygwin原来的设置都是一样的: browse-url-default-windows-browser
    • 虽然缺省shell改成了bash (由Cygwin提供的环境变量SHELL决定),但你应该可以用(let ((shell-file-name "cmd")) (shell))的方式来运行cmd(不过我不推荐你用(setq shell-file-name "cmd")修改掉缺省的shell——调用很多外部程序时需要这个设置,而cmd实在是配合不好)

3. 为什么不用native win32 gui版本?

这主要是Cygwin的优势了:

从安装的方便性上来说,很多外部程序(比如find, grep, diff, git),你不用繁琐地到处去寻找win32 native port来安装了,你可以很方便地安装和使用cygwin的版本(在此推荐一下cyg-apt  t,你只要简单地cyg-apt install w3m就可以安装上w3m了。另外[url=]我也略做过改进,以支持多个repo),何况有些程序目前没有win32 native port,比如dict, sdcv

目前发现的一些小问题:

* 窗口没有图标(我发现nt/emacs.rc并没有被编译、包含进可执行文件,但手工加了一下之后,窗口还是没有图标——待有空仔细看看代码看问题在哪里)

 

附两张截图:

Emacs 24.2.90 cygwin build, with Win32 GUI  


快写完的时候,邮箱收到了cygwin-announce邮件列表的通知,说是已经提供了23.2.90的测试版本,这次新增的w32 gui版本也提供了,所以你只要打开Cygwin setup.exe,选择安装emacs-w32就可以了。
如果你用cyg-apt的话,那么就是这么几步:

cyg-apt setup #第一次运行cyg-apt的话,需要用这个建立配置文件~/.cyg-apt
cyg
-apt update # update setup.ini
cyg
-apt install emacs-w32



P.S. 根据这个HAVE_MOUSE补丁,新的Emacs不需要跟X11库链接也可以在terminal下支持鼠标了(这个补丁也可以在老版本的Emacs源代码上使用)——但你还是需要在运行期执行M-x xterm-mouse-mode打开鼠标支持

本文链接



(automatically copied by ifttt from http://www.cnblogs.com/bamanzi/archive/2012/12/08/emacs-24_3-cygwin-w32-gui.html)

2012年12月3日星期一

[Emacs] 小技巧: 高亮/修改所有同名符号

(此篇面向初级用户,写的比较啰嗦,请中高级用户见谅。

其实这篇的草稿是9月初写的,躺在草稿箱里面3个月了,最近工作和生活都比较忙,没时间来整理格式 :-( )

** hi-lock-mode

Emacs自带hi-lock-mode (hi-lock.el),里面提供了一下几个很有用的命令:

  • highlight-phrase (M-s h p)
  • highlight-regexp (M-s h r)
  • highlight-lines-matching-regexp (M-s h l)

使用时直接输入上面命令或快捷键即可,不用先打开 hi-lock-mode ,Emacs会自动打开。

使用时Emacs会先问你要高亮什么内容,如果你不想手工输入的话,得事先拷贝好内容再在这里粘贴。

然后Emacs会问你使用那种风格(face)来显示高亮,除了hi-lock.el提供的 hi-yellow, hi-pink, hi-green 等颜色之外,你也可以使用Emacs里面其它的face。

要去除高亮,用 M-x unhighlight-regexp (M-s h u),它会自动提供当前已有条目(刚才通过上 述三个命令输入的内容)供你选择。

** highlight-symbol

http://nschum.de/src/emacs/highlight-symbol/

这个第三方库其实是对hi-lock-mode的封装,使得用户用起来更方便:

  • highlight-symbol-at-point: 因为大多数时候我们只关注当前焦点所在的符号,所以可以省略输入高亮内容那一步,颜色也不用用户输入了,它会自己随机挑一个,这个命令正是这样工作的;

  • 可以方便地跳转到当前符号的上一次/下一此出现位置(highlight-symbol-prev, highlight-symbol-next)

  • 还可以限定只在当前函数里面查找(highlight-symbol-next-in-defun, highlight-symbol-prev-in-defun)

这就跟vim用户很喜欢的*和#键功能差不多了,我绑定的快捷键也是沿用了这两个符号:

(require 'highlight-symbol) ;;Use autoload' oridle-require' if you like

(global-set-key (kbd "M-s j") 'highlight-symbol-at-point)
(global-set-key (kbd "<C-double-mouse-1") 'highlight-symbol-at-point)

(global-set-key (kbd "M-s *") 'highlight-symbol-next)
(global-set-key (kbd "M-s #") 'highlight-symbol-prev)

(global-set-key (kbd "C-*") 'highlight-symbol-next)
(global-set-key (kbd "C-#") 'highlight-symbol-prev)

后两个(C-*, C-#)是为了应付连续按的场景的,单次按键比多次要方便一点。不过这两个组合键在term(console, gnome-terminal, putty等)下面是没法用的(我比较少有在term下用emacs,如果用得比较多,倒是可以考虑绑定到M-*和M-# 上)。

** idle-highlight

https://github.com/nonsequitur/idle-highlight-mode

很多朋友很喜欢能够自动高亮当前焦点所在的符号,当焦点移开之后又自动取消高 亮, idle-highlight.el 就是干这个的。

idle-highlight.el放到load-path内,然后在dotemacs里面加入:

(autoload 'idle-highlight-mode "idle-highlight" "highlight the word the point is on" t)

使用时只要M-x idle-highlight-mode RET 就可以了。

如果想打开文件时自动开启该功能 如果要自动对所有文件都打开该功能,在dotemacs里面加入:

 

(add-hook 'find-file-hook 'idle-highlight-mode)

 

如果只对某些主模式打开,则加入:

(add-hook 'emacs-lisp-mode-hook 'idle-highlight-mode)
(add-hook 'python-mode-hook 'idle-highlight-mode)
(add-hook 'js-mode-hook 'idle-highlight-mode)

Emacs 24里面将所有编程语言的major mode做了变更,都变成继承自prog-mode了,这种情况下只 需要这样就可以对所有编程语言添加此功能(而其它文本编辑不受影响):

(add-hook 'prog-mode-hook 'idle-highlight-mode)

** semantic-idle-local-symbol-highlight-mode

CEDET里面提供了一个 semantic-idle-local-symbol-highlight-mode ,跟idle-highlight功能类 似,但依赖于CEDET的语法解析功能。我不怎么用CEDET,所以不能给出评价。有兴趣的可以看看Emacs中文网的这篇 [用CEDET浏览和编辑C++代码] 里面的 [相应说明]。

** iedit

https://github.com/victorhge/iedit/

http://www.emacswiki.org/emacs/Iedit

修改代码的时候尝尝需要对函数名、变量名进行修改,这就需要对同一符号的多次出现 (occurrence)进行批量替换(这个活儿在重构里面叫做rename method 或者rename field

iedit.el可以部分实现这个目标。之所以说"部分"是因为它只是个编辑功能,只能应付单一文件的 情况,做不到基于工程或者语法来修改所有调用到的地方。

iedit.el提供的iedit-mode是个临时模式,使用方法如下:

1. 加载iedit.el,将iedit.el放到site-lisp目录下,然后

  a). 动态加载: M-x load-library RET iedit.el RET

  b). Emacs启动时加载: 在dotemacs里面加入:

(autoload 'iedit-mode "iedit"
"Edit multiple regions with the same content simultaneously." t)
2. 需要修改某个符号(函数名、变量名)时,将光标移动到该符号上,然后 M-x iedit-mode RET (或者按C-; 这是缺省配置的快捷键)即可进入批量修 改模式,使用该符号的所有地方会被高亮。通过编辑修改该符号的名称,所做改动会即时反馈到所有高亮的地方。

3. 修改完成后,重新输入 M-x iedit-mode RET 退出此模式。

如前所说,iedit比较简单,没有语法分析能力,所以如果你一个文件里有两个类用了同名的变 量,它也区分不了,解决办法是结合Emacs Narrowing来实现: Emacs narrowing功能使得我们可以只编辑一个文件的一部分,而其它部分并不在可编辑范围内。所以实现上述目标的方法是:

1. 选择(mark)要修改的函数(C-M-h)或者类;

2. 输入 M-x narrow-to-region (或者 C-x n n), 如果你是第一次使用这个功能,Emacs 会问你是否要启用该功能(因为这个功能会导致初学者晕头,所以为防止误入,缺省被禁用了);

3. 好了,Emacs现在只显示你选中的那一块代码了,你现在做全buffer的替换,并不会影响文件的其它部分:用上面的 M-x iedit-mode RET 来做替换吧;

4. 修改完成,再用C-; 退出iedit-mode

5. 用 M-x widen RET (或者 C-x n w) 回到编辑整个文件的模式

 

参考: - emacs-fu: interactive replacement

** 其它补充

* auto-highlight-symbol-mode

https://github.com/mitsuo-saito/auto-highlight-symbol-mode/wiki/

这是写这篇文章时翻到的一个扩展,看说明它用一个el文件把上述几个功能都包含了,并不需要三个文件:

  • automatic highlighting current symbol like eclipse IDE.
  • cycle through highlighted locations.
  • can specify the range to highlight.
  • can edit the highlighted symbols at a time.

我还没有试过,有兴趣的朋友自己试试吧。

 * occur: 列出所有包含某个符号的行

M-x list-matching-lines RET (缺省绑定到了M-s o) 然后输入要查找的符号即可。Emacs会在一个新的窗口列出结 果,可以用 M-g n和M-g p 跳转到下一次、上一次出现的地方。(注: 此命令有个比较简短的别名: occur ),

如果想将当前符号作为输入,免去每次输入的麻烦,可以用下面这个函数:

(require 'thingatpt)

(defun occur-at-point (nlines)
(interactive "P")
(occur (format "%s" (thing-at-point 'symbol)) nlines))

(define-key search-map "O" 'occur-at-point)

要深入研究一下occur的话: http://emacswiki.org/emacs/OccurMode

本文链接



(automatically copied by ifttt from http://www.cnblogs.com/bamanzi/archive/2012/12/03/emacs-find-modify-all-occurences.html)