当前位置: 首页 > news >正文

emacs-shell

<?xml version="1.0" encoding="utf-8"?> emacs-shell
UP | HOME

emacs-shell

Table of Contents

  • 1 Emacs下shell的学习
  • 2 第一回引子
  • 3 第二回初识 Shell mode – 窗口篇
  • 4 技巧一
  • 5 技巧二
  • 6 第三回甜蜜约会 – buffer 篇
  • 7 小技巧

1 Emacs下shell的学习

Location: http://www.ibm.com/developerworks/cn/linux/l-cn-emacs-shell/index.html

当 Shell 遇见 Emacs – 大话 Emacs Shell Mode

简介: GNU Emacs 有很多“神奇”的功能。常言说“每一个 hacker 都有一个自己的 GNU Emacs”。这个事实在很大程度上得益于人们能够按照 完全自我的方式去使用 GNU Emacs。将 Shell 运行在 GNU Emacs 里面就是众多的用法之一。在 GNU Emacs 里面运行 Shell 有很多种不同 的方法。包括各种各样的终端模拟。但是在笔者的工作当中更多的使用的是 Shell-mode 的方式。在这种方式下,可以最大限度的利用 GNU Emacs 所具有的各种神奇能力,让日常工作变得前所未有的轻松、有趣。

2 第一回引子

GNU Emacs 是一个非常强大的编辑器,这个编辑器不仅可以用来写文章,写程序,更重要的是,他可以和一些原本看似没有明显关系的应用 程序在一起,合作创造出一些新的“不可思议”的应用。比如说可以在 GNU Emacs 里面运行你的 Shell。

通常来说人们在 Linux 或者 Unix 上面工作的时候,不论是在本机工作,还是登录到地球另一头的远端机器,都是使用各种各样的终端或者 终端模拟器来运行 Shell。最常见的例如 xterm,rxvt,以及 Putty 之类的终端模拟器。与此对应,GNU Emacs 也有自己的终端模拟器,例 如 ansi-term,multi-term 等等。这些终端模式,使得你可以像在在其他终端当中一样工作,甚至可以在 Emacs 的终端里面运行 Vim。

但是,今天要和大家分享的是另外一种使用方式—— Shell mode。这是一种完全不同的工作方式。这种方式和大家常用的工作方式最大的一个 区别,就是在这里完全没有任何 terminal 的存在。用户实际上是工作在一个 Emacs 的文本缓冲区里面,并不直接和 Shell 进行交互。一 切的命令输入都是写入到这个文本缓冲区当中,经由 comint.el从缓冲区中读取,然后转交给后台的 Shell 进程。Shell 产生的输出再由 comint.el进行收集,然后写入到用户所用的这个缓冲区当中来。这个缓冲区在 Emacs 当中叫做 Shell 缓冲区 (Shell buffer)。

启动一个 Shell 缓冲区并且进入 shell mode 的过程非常简单。只需要在 Emacs 当中按下 Meta-x 组合键(在现在的键盘上通常是 Alt-x 组合键),然后输入命令 shell 并回车,Emacs 就会启动一个 Shell 进程并且打开一个与之关联的 Shell 缓冲区。Shell 缓冲区的名字通 常会是 *shell*。具体启动什么样的 Shell 进程通过 Emacs 配置文件里的 shell-file-name 变量指定,或者由用户的环境变量 SHELL 或 EMACSSHEL 来指定。通常的写法是

(setq shell-file-name "/bin/bash")

或者

export EMACSSHELL=/usr/bin/zsh

另外如果你希望使用一个支持 ANSI color 的 Shell 进程,那么最好在你的 Emacs 配置文件里面加入下面两行,以便在执行 ls – color=auto 命令的时候输出的色彩信息能够被 Emacs 正确解析。

(autoload 'ansi-color-for-comint-mode-on "ansi-color" nil t)
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on t)

说了这么多了,这种工作方式究竟能有什么好处呢?我为什么要离开熟悉的 Xterm,把我的 Shell 搬到 Emacs 当中来呢?


3 第二回初识 Shell mode – 窗口篇

下面我们就来谈谈好处。事实上不仅仅是好处,在相当程度上甚至是不可替代性。

第一个明显的好处就是多窗口的工作模式。

通常在人们的工作当中都会打开多个终端,同时进行几份工作。在这个时候就需要对这些终端窗口进行排列和管理(在这里假设你工作在图 形化环境之下)。而且通常需要频繁的使用鼠标在不同的窗口之间切换焦点。为了避免窗口之间相互遮盖,你也许会通过精心编辑的 .Xdefaults文件使得两个或四个终端窗口恰到好处的平铺在整个屏幕当中。但是仍然需要使用鼠标在不同的窗口进行切换,在不同的窗口之 间复制粘贴信息……这些窗口维护的工作在任务繁忙的时候会很繁重。并且如果这时候需要的不止 4 个窗口,或者你还需要进行额外的文字编 辑的工作……最终窗口还是会要么被覆盖起来,要么被挤到别的虚拟桌面。

在这种时候最好来试试 GNU Emacs。GNU Emacs 天生具有完善的窗口管理功能,并且完全不依赖于 X Window。这是因为 GNU Emacs 的诞生 要远远早于 X Window 的历史。在 GNU Emacs 里面你只需要按下 Ctrl-x 2 组合键就可以把当前窗口切分成上下两个等分的窗口,

    +----------------------+
    |                      |
    |                      |
    +----------------------+
    |                      |
    |                      |
    +----------------------+

   按下 Ctrl-x 3组合键又可以把当前窗口切分成左右两个等分的窗口。这些切分可以一直进行下去。

    +----------+-----------+
    |          |           |
    |          |           |
    +----------+-----------+
    |                      |
    |                      |
    +----------------------+

   输入 Ctrl-x 0可以关闭当前光标所在的窗口。

    +----------------------+
    |                      |
    |                      |
    +----------------------+
    |                      |
    |                      |
    +----------------------+

   输入 Ctrl-x 1组合键则可以关闭其他所有窗口,并使当前光标所在的窗口成为最大的窗口。

    +----------------------+
    |                      |
    |                      |
    |                      |
    |                      |
    |                      |
    +----------------------+




当你使用两个或以上的窗口的时候,可以使用 Ctrl-x o(注意是小写字母 o)组合键在各个窗口进行移动。通过给 Ctrl-x o组合键加上数 字前缀,例如 Ctrl-u 3 Ctr-x o 或者更加简洁的 Meta-3 Ctrl-x o 就可以在多个窗口之间快速的移动。

当然,当你启动了太多各种缓冲区的时候,总归是要把其中的一些覆盖掉的。因为保证工作窗口具有足够的可视面积才是真正有意义的事。 在这种时候可以通过 Ctrl-x b 组合键在所有缓冲区之间方便的切换。或者通过 Ctrl-x Ctrl-b 组合键得到所有缓冲区的列表。

这种缓冲区的切换和 X Window 窗口或者虚拟桌面之间的切换最大的不同在于——如果你有任意两个或者多个缓冲区的工作需要相互参照(这 样的需要会非常常见),甚至就是信息的复制粘贴,这个时候相关的工作窗口最好能分布在同一个屏幕上。在 GNU Emacs 当中你将很容易把 这些需要参照的缓冲区切换到同一个屏幕的窗口当中去。而在图形终端的工作方式下,这些需要参照的窗口常常要么恰好是相互覆盖的,要 么恰好是处在不同的虚拟桌面之中,频繁的拖拽移动将会变得非常繁琐。

还有一种情况,由于工作的原因恰好需要对同一个 Shell 进程当中的内容进行上下文参照……通常绝大多数终端都不提供这种功能。但是在 Emacs 里面,同一个缓冲区显示在两个独立的窗口里面完全不成问题。

另外如果你很喜欢多个虚拟桌面的工作方式,可以使用 make-frame 命令生成多个 frame( 也许可以叫做“窗框”),把他们放到多个虚拟桌面 当中去。而且即使是在这种情况下,仍然可以使用 Ctrl-x b 组合键在任何一个 frame 中的任何一个窗口中切换到任何一个被遮盖的缓冲区 。不需要进行任何 X Window 当中的窗口移动和桌面切换,包括进行上下文参照。

4 技巧一

如何在 GNU Emacs 当中启动多个 Shell 进程及其对应的 Shell 缓冲区?

我在上文当中提到了那么多的窗口,但是如果你在 minibuffer 当中第二次输入 Meta-x shell 命令,GNU Emacs 会把你带到已经存在的那 个名叫 shell 的 Shell 缓冲区,而不是创建一个新的。解决的方法非常简单——你只需要使用 rename-buffer 命令为现有的 Shell 缓冲 区重新安排一个名字,然后再执行 shell 命令,GNU Emacs 就会为你创建一个新的名叫 shell 的 Shell 缓冲区了。因为这两个命令在我 的工作中用的非常频繁,所以我把它们绑定到了两个快捷键上面

(global-set-key (kbd "C-c z") 'shell)
(global-set-key (kbd "<f10>") 'rename-buffer)

5 技巧二

如何 undo 到我刚刚离开的窗口设置?

上文提到过,Ctrl-x 0, Ctrl-x 1, Ctrl-x 2, Ctrl-x 3 能够快速的更改 GNU Emacs 的窗口设置,但是如果我在用过 Ctrl-x 1 之后希望 能够快速“退回”到“刚才”使用过的窗口设置,而不是把它再做一遍,有没有办法做呢?GNU Emacs 有一个叫做 winner-mode 的 minor mode 可以帮你完成这个愿望。

只需要在你的 Emacs 配置文件里面加入下面几行

(when (fboundp 'winner-mode)
 (winner-mode)
 (windmove-default-keybindings))

然后就可以使用 Ctrl-c ← (对,就是向左的箭头键)组合键,退回你的上一个窗口设置。


6 第三回甜蜜约会 – buffer 篇

上文描述了在 GNU Emacs 里面通过简单的窗口管理优化 Shell 工作的方法,是不是开始对 Shell 从终端里面搬到 Emacs 里面开始有了一 点点的心动了呢?别着急,这还只是个开始,目前你看到的都还只是外表。接下来让我们和 Emacs 来一个甜蜜的约会吧。

输入

我在开头的引子部分曾说过,在 Shell mode 中工作的时候,用户实际上接触的是一个文本缓冲区,实际上并没有直接的跟 Shell 进程打任 何交道。这也是和通常的终端模式的工作方法的一个非常大的区别。虽然这个区别看起来似乎不是那么显著(那是因为这个 Shell 缓冲区被 设计成了看起来很像一个图形终端的样子),但是实际上这点区别将会带来一些不可替代的优势。让我们来先看一个简单的例子:

让我们在 Shell 提示符前输入这样一行命令

#!/bin/bash

 2 : 2037 : 13:04:40 : ~
 dove@bash-4.1$  cd /usr/share/emacs

 2 : 2038 : 13:05:05 : /usr/share/emacs
 dove@bash-4.1$ ls -1
 23.1
 site-lisp
 site-lisp.tar

 2 : 2039 : 13:05:09 : /usr/share/emacs
 dove@bash-4.1$


这个时候让我们把光标移动到 23.1 的前面,输入 ls -1加空格,

#!/bin/bash

 2 : 2037 : 13:04:40 : ~
 dove@bash-4.1$  cd /usr/share/emacs

 2 : 2038 : 13:05:05 : /usr/share/emacs
 dove@bash-4.1$ ls -1
 ls -1 23.1
 site-lisp
 site-lisp.tar

 2 : 2039 : 13:05:09 : /usr/share/emacs
 dove@bash-4.1$


然后回车。接下来就会看到这样的输出结果出现在缓冲区里面。

 2 : 2040 : 13:08:55 : /usr/share/emacs
 dove@bash-4.1$ ls -1 23.1
 etc
 leim
 lisp
 site-lisp

 2 : 2041 : 13:09:06 : /usr/share/emacs
 dove@bash-4.1$



这是一件很有意思的事情,因为我们并没有像在终端当中常见的那样在 Shell 提示符的后面进行命令输入,而是在一个看起来非常随意的地 方。神奇的是他居然被正确地执行了。事情的真相其实很简单。

因为现在我们是在一个被称作 Shell 缓冲区的文本缓冲区里面。这就是一个很普通的文本缓冲区,它具有所有其他文本缓冲区所具有的一切 特性。你可以在任何时候,任何位置,对这个缓冲区里的任何文本内容进行任何编辑。因为他就是文本。直到某一刻,你在其中一个文本行 上面按下了回车,这时 comint.el 就会负责把当前光标所在行的内容提取出来,发送给 Shell 去执行,然后将 Shell 执行的结果以及一个 提示符(这个提示符实际上也是由 Shell 输出给 comint.el 的)以文本的形式添加到这个缓冲区的末尾。

这个例子并不仅仅是列一个目录那么简单,事实上他提供了一个更加强大的工作方式 —— 曾经只能用来阅读的命令输出现在也可以被用来构 造新的命令了。让我们再来看一个新的例子,在这个例子中我们将把这种能力与 Bash 的历史命令引用的能力结合起来

 2 : 2044 : 15:16:17 : /usr/share/emacs/23.1
 dove@bash-4.1$ ls -1
 etc
 leim
 lisp
 cd ../site-lisp && !!

 2 : 2045 : 15:16:49 : /usr/share/emacs/23.1
 dove@bash-4.1$ cd ../site-lisp && !!
 cd ../site-lisp && ls -1
 auctex
 auctex.el
 autoconf
 autoconf-mode.el
 autotest-mode.el
 bashdb.el
 bashdb.elc
 bbdb

如果这时候我需要列出 auctex.el 文件的内容,我只需要在在各文件名前面输入 head,然后回车就行了

 2 : 2045 : 15:16:49 : /usr/share/emacs/23.1
 dove@bash-4.1$ cd ../site-lisp && !!
 cd ../site-lisp && ls -1
 auctex
 head auctex.el
 autoconf
 autoconf-mode.el
 autotest-mode.el
 bashdb.el
 bashdb.elc
 bbdb

 2 : 2046 : 15:17:16 : /usr/share/emacs/site-lisp
 dove@bash-4.1$ head auctex.el
 ;;; auctex.el
 ;;
 ;; This can be used for starting up AUCTeX.  The following somewhat
 ;; strange trick causes tex-site.el to be loaded in a way that can be
 ;; safely undone using (unload-feature 'tex-site).
 ;;
 (autoload 'TeX-load-hack
  (expand-file-name "tex-site.el" (file-name-directory load-file-name)))
 (TeX-load-hack)

 2 : 2047 : 15:23:53 : /usr/share/emacs/site-lisp
 dove@bash-4.1$

这看起来已经不太像是在运行 Shell 了,倒象是在与某人合作编写一篇巨大的文章了,而 Shell 就是你的合作者。如果你真这么想的话, 那就非常好了。至少你已经从枯燥乏味的日常工作当中找到些许的乐趣了。

7 小技巧

如果你登录在一台远程机器上工作,cat 一个文件后,需要把这个文件的内容保存到本地来,那么完全不需要启动一个 FTP session 去下载 这个文件。你只需要选中缓冲区里面的文件内容,按下 Meta-x 组合键,输入 write-region 命令就可以把选中的内容保存在本地文件当中 。

Date: 2013-01-11 Fri

Author: liweilijie

Org version 7.9.2 with Emacs version 23

Validate XHTML 1.0

转载于:https://www.cnblogs.com/liweilijie/archive/2013/01/11/2856208.html

相关文章:

  • WPF 去除头部,实现拖动
  • shell四大变量和实例_李强强
  • 通过SharpShell快速实现Windows Shell扩展
  • 简明 Vim 练级攻略 | 酷壳 - CoolShell.cn
  • 简单.net 数组
  • C# List数据类型的简单使用
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • CentOS VNC安装
  • 一个(次)线程的生命史
  • 查看内存使用情况(转)
  • 《算法导论》读书笔记之第6章 优先级队列
  • 自动文字提示列表
  • keyboard Button
  • App应用里应该自动跳转到系统设置界面吗?
  • 使用phantomjs获得web页面截图 | Marshal's Blog
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 10个最佳ES6特性 ES7与ES8的特性
  • 11111111
  • Angular 2 DI - IoC DI - 1
  • Brief introduction of how to 'Call, Apply and Bind'
  • canvas 五子棋游戏
  • CSS实用技巧干货
  • hadoop集群管理系统搭建规划说明
  • iOS | NSProxy
  • JavaScript设计模式与开发实践系列之策略模式
  • markdown编辑器简评
  • Spring Boot MyBatis配置多种数据库
  • vue的全局变量和全局拦截请求器
  • 分布式事物理论与实践
  • 机器学习中为什么要做归一化normalization
  • 前端存储 - localStorage
  • 通过git安装npm私有模块
  • 微信公众号开发小记——5.python微信红包
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 正则学习笔记
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • 说说我为什么看好Spring Cloud Alibaba
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • # 数据结构
  • #includecmath
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (二)Linux——Linux常用指令
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)nsfocus-绿盟科技笔试题目
  • (转)shell调试方法
  • .Net Memory Profiler的使用举例
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET委托:一个关于C#的睡前故事
  • /etc/fstab和/etc/mtab的区别
  • [APUE]进程关系(下)