终端和键盘
在Unix最初的时候,没有独立的键盘和鼠标,独立的显示器也非常昂贵。Thompson 和 Ritchie 选用了价格不贵并且容易获得的Teletype ASR33作为解决方案,虽然Teletype ASR33完全是为了电传而设计的。Teletype有一个键盘用来输入,宽的纸卷用来打印输出。为了保存程序和数据,它还有一个纸带打孔机(用来在又长又窄的纸带上打孔)和一个纸带阅读器(读取打孔纸带上的数据)。
当用户使用Teletype ASR33打错字符时,由于输出结果的打印部分不能回退,即没有BackSpace键来删除错误(字符打印到纸上不能擦除)。Unix内核不得不允许微小的错误——删除前一个字符和kill(删除整行)输入行——使用一些“特殊”字符用来控制程序。Teletype只能打印,不具备清除功能,所以最初的UNIX选用的清除和kill整行控制命令只能是平常可以打印的字符,也就是#(删除前一个字符)和@(删除整行)。
UNIX如何控制终端
Unix就是被设计成用户使用终端访问主机的系统。其中一个非常重要的问题需要被克服:每一种终端都有它自己的字符和命令集。主机需要知道终端的信息才能控制终端的显示。这个问题的解决方案就是收集所有不同类型终端的描述。这样子,当一个程序想发送命令给终端时,它可以使用在数据库中存放的终端信息来发送标准的命令。最初的终端数据库是termcap (terminal capabilities)。后来由于终端越来越多,数据库越来越大,使用起来也原来越慢,terminfo采用了不同方式来整理组织数据库,也就慢慢替代了termcap。
终端如何控制UNIX
在过去的很多年里,存在很多带有不同键盘的多种终端,Unix都能与这些终端工作。这是因为Unix采用了灵活的键盘映射系统,支持任何键盘。Unix使用一组键盘信号来控制程序的运行。由于这些信号是标准的,发送信号的实际按键可以改变。
在打字过程中可以使用的信号有erase,werase和kill。erase删除最后输入的字符,werase删除最后输入的单词,kill删除整行。
停止程序的键盘信号是intr,文件结束的信号是eof。
我们可以使用 stty -a 来查看我们的键盘映射,也可以使用 stty 命令来改变我们的键盘映射。需要注意的一点是在Unix/Linux系统常常使用Ctrl键来组合其他的键发送信号,为了省事使用caret(^)字符来代替Ctrl键。
linux bash的键盘trick
^A: 将光标挪到行的开始。
^E: 将光标挪到行的末尾。
^F: 将光标向右挪一个字符,相当于方向键->。
^B: 将光标向左挪一个字符,相当于方向键<-。
^P: 挪到上一条历史记录,相当于方向键UP。
^N: 挪到下一条历史记录,相当于方向键DOWN。
^L: 清屏,并将光标移到左上角,相当于clear命令。
^D: 删除当前光标处的字符。
^H: 删除光标前的一个字符。
^W: 删除光标前的一个单词。
^U: 删除光标到行首的内容。
^K: 删除光标到行尾的内容。
^Y: 复制剪贴板中的内容并插入到当前光标处。
^R: 对命令进行逆向搜索,即对历史记录从后向前搜索。
^J: 对^R找到的命令复制到shell提示符下。
^O: 对^R找到的命令进行执行,并准执行下一条命令。
!!: 重复执行上一条命令。
!$: 显示上一条命令的参数,当上一条命令没有参数时则显示该命令。
^pattern^replacement: 将上一条命令中的pattern替换成replacement。
Vi的使用
vi编辑器是Unix传统中的核心程序之一。它不仅存在于所有的Unix和Linux系统中,而且功能极其强大。Vi是visual editors的简写,目的是为了在带有移动光标的可视终端(video terminal)上编辑。在可视化编辑器之前是一次只能在一行上操作的行编辑器(line editors)。由于可视终端的出现,可视化编辑才成为可能。事实上vi还包含了功能强大的行编辑ex,我们可以在使用vi时使用行编辑命令。现在大多数Linux版本并不包含真的vi,而是包含它的增强版本vim(Vi IMproved的缩写)。vim对vi进行了重大的改进,通常在linux系统上符号性地链接(或者alias)到名字vi。
用vi工作的时候,数据存储在编辑缓冲区(EDITING BUFFER)。当你告诉vi想编辑一个文件,vi复制该文件的内容到编辑缓冲区,所以你编辑的是你数据的拷贝,而不是原始数据。在最初的时候,键盘(如图是:Keyboard layout of the ADM-3A terminal) 上没有现在这么多功能键,除了字母、数字和标点符号外还有<Shift>,<Ctrl>,<Return>和<Esc>键而已。没有鼠标,也没有方向键。所以没有直观的方式让用户指明命令,如插入、修改、删除、复制或者黏贴。此时采用的方案就是将vi设计成两种不同的模式。命令模式,敲入的所有键都被解释成命令;输入模式,敲入的所有东西都被直接放进编辑缓冲区。命令模式中的命令又分两种,一种是vi命令,一般是一两个字符,输完命令不需要回车就会执行;另外一种是ex命令,需要先输入冒号(:),接着是命令,最后是回车执行。那vi是如何使用屏幕的呢?屏幕最下面的一行叫做命令行(COMMAND LINE),这一行有两种用处:显示消息和显示你敲入的某种命令。屏幕上的其他行则用来显示数据。
基本操作
vi [-rR] [file...]:启动vi, -r (recovery),-R (read-only), file是想要编辑的文件。因为vi会在编辑过程中自动将编辑缓冲区的内容保存到交换文件中,在异常发生后,交换文件就保存在编辑文件所在目录下。交换文件的名字一般是以点号(.)开头,后跟文件名,最后是(.swp)。不管恢不恢复文件,做完决定后要记得将交换文件删掉(vi不会自动删除),否则编辑原文件会一直提醒是否要恢复文件。
ZZ :保存编辑的内容并退出。
^V :用于在文本中插入控制字符。比如说想在文本中插入^I,则需要输入^V^I,插入^V,需要输入^V^V。
^L :用于刷新屏幕,比如说使用远程连接是,有些行显得比较混乱,可以使用此键。
^G:查看当前编辑文件以及光标所在的位置。
:q! :放弃编辑的内容并退出。
:w [filename] :保存编辑的内容。
移动光标 :可以在这些命令的前面输入一个数字,指明这些命令的重复次数。
h:向左移动一字符,类似于方向键左。
j:向下移动一行,类似于方向键下。
k:向上移动一字符,类似于方向键上。
l:向右移动一字符,类似于方向键右。
0:将光标移到当前行的开头,0是数字0。
$:将光标移到当前行的末尾。
^:将光标移动到当前行的第一个非空格/Tab的字符。
w:将光标移动到下一个单词的第一个字符。
e:将光标移动到下一个单词的最后一个字符。
b:将光标移动到前一个单词的第一个字符。
W:跟w一样,不过忽略了标点符号。
E:跟e一样,不过忽略了标点符号。
B:跟b一样,不过忽略了标点符号。
):将光标移动到下一句。
(:将光标移动到上一句。
}:将光标移动到下一段。
{:将光标移动到上一段。
H:将光标移动到屏幕的第一行。
M:将光标移动到屏幕的中间行。
L:将光标移动到评论的最后一行。
^F:向下移动一屏。
^B:向上移动一屏。
^D:向下移动半屏。
^U:向上移动半屏。
gg:跳到文件的第一行。
G: 跳到文件的最后一行。可以指定要跳的行号,比如说要跳到81行,可以输入81G。
:n :跳到第n行。
:$ :跳到最后一行。
``:跳到前一个跳转的位置,`. 跳到之前编辑的位置,`" 跳到上次离开文件时的位置。
m:给当前位置起名字。例如可以在这个位置输入ma,这一位置的名字就是a,将来可以使用`a跳到这个位置,‘a跳到这个位置所在行的开头。
查找
/: 从当前位置开始向下查找。
?:从当前位置开始向上查找。
n:沿着最初的命令方向搜索下一个。最初如果是/(向下)搜索,则继续向下;如果是?(向上)搜索,则继续向上。
N: 逆着最初的命令方向搜索下一个。最初如果是/(向下)搜索,则向上反序搜索;如果是?(向上)搜索,则向下搜索。
插入文本
i:在光标之前插入。
a:在光标之后插入。
I:在光标所在行的开头插入。
A:在光标所在行的末尾插入。
o:在当前行之后另起一行插入。
O:在当前行之前另起一行插入。
修改文本
r:修改单个字符,但并不进入到输入模式。
R:进入输入模式,依次覆盖所在行的光标后的字符。
s:进入输入模式,以插入的方式替换掉一个字符。
C:进入输入模式,以插入的方式替换掉光标到行尾的所有内容。
S或者cc : 进入输入模式,以插入字符的方式替换掉当前行。
c move:进入输入模式,以插入字符的方式替换掉光标到move间的内容。
替换文本 (. 代表当前行,$代表最后一行,%代表所有行)
:s/pattern/replace/ :在当前行中进行替换
:lines/pattern/replace/ :在第line行进行替换
:line,lines/pattern/replace/ :对两个line中的所有行进行替换
:%s/pattern/replace/ :对所有行进行替换
删除文本
x :删除光标处的字符
X :删除光标左侧的字符
D :删除光标到行末尾的字符
d move : 删除从光标到move的内容
dd :删除整行
:lined :删除指定行
:line,lined :删除两个line间的所有行
取消或者重复修改
u :取消最后一个命令所在的修改
U :恢复当前行
. :重复上一个修改命令,只限于对编辑缓冲区进行了改变的命令,如编辑、修改、替换、删除等
当你删除了文本中的一行或者多行的时候,vi会将删除的内容保存在一个叫做NUMBERED BUFFER的特殊位置。一个有九个这样的缓冲区,从1到9编号。越是最近删除的内容,编号越小。当你想取出最近删除的几行内容时,可以通过 "1p 或者"2P。你可以使用双引号加缓冲区的编号,后加p或者P命令。用.(period)重复这个命令时,vi会自动将编号加1。
移动文本
vi会自动将最后一次删除的内容保存在一个叫做UNNAMED BUFFER的位置。这样子就可以使用p和P命令将删掉的内容挪到到需要的地方。
:x[,y]mz :将x行与y行间的所有内容移动到z行的下一行。m代表move。
复制文本
vi将复制的文本内容也是存放在NUNAMED BUFFER中。这样子就可以使用p和P命令将复制的内容黏贴到需要的地方。
y move :复制光标到move间的内容。
yy 或 Y :复制整行。
:x[,y]coz :将x行与y行间的内容复制到z行的下一行。co代表copy。
黏贴放置文本(put)
p (lower):在光标后放置文本,如果UNNAMED BUFFER中的内容是以 行 为单位的话,则在光标所在行后另起一行放置文本。
P (upper):在光标前放置文本,如果UNNAMED BUFFER中的内容是以 行 为单位的话,则在光标所在行前另起一行放置文本。
大小写替换
~ : 将大写字母替换成小写,将小写字母替换成大写。只对字母起作用,可以在~前加上数字,可以对光标后的几个字符进行该操作。
行与行链接
J :将光标所在行与下一行链接成一行(去掉换号符)。可以在前面加上数字,将可以将光标下的几行链接成一行。
设置选项
有两种vi选项: 一种是开关类的选项,使用 :set [no]option... ;另一种是变量形的选项,使用 :set option[=value]...。
显示选项
:set all :显示所有的选项
:set :显示所有改变了默认值的选项
:set option? :显示选项option的值
输入shell命令
:!command :暂停vi,执行command命令
:!! :暂停vi,执行上一条shell命令
:sh :暂停vi,新启动一个(默认)shell
:!bash :暂停vi,新启动一个Bash shell
插入其他文本
:[line]r file :读取file中的内容,将其插入到第line行下面
:[line]r !program :将程序program的执行结果插入到第line行下面
用程序处理数据
n!!program :调用program处理当前行在内及其下的共n行数据
!move program:调用program处理当前行到move间的数据
将数据写到文件
:w :将数据写到原文件
:w file :将数据写到一个新文件file
:w! file :覆盖已有的文件file
:[x[,y]]w>> file : 将x与y间的所有内容添加到file末尾;不指定y,则只将第x行添加到file末尾;不指定x和y,则将所有内容添加到file末尾。
编辑另一个文件
:e file :编辑文件file
:e! file :编辑文件file,放弃现在修改的内容
:e! :放弃修改的内容,重新编辑现在的文件
编辑多个文件
vi file1 file2 file3... :打开file1、file2、file3等多个文件。
:n :切换到下一个文件。
:N :切换到上一个文件。
:buffers :查看当前编辑的文件列表。注:这是vim命令。
:buffer n :切换到第n个文件上。注:这是vim命令。
使用简写 abbreviate
:ab [short long] :short是简写,long是简写要替换的长文本。该命令将长文本long简写成short。如果不带参数,则列出当前定义的所有简写。
:una short :取消简写short。una代表un-abbreviate。
宏
:map [x commands] :x是一个字符,commands是一系列的vi或者ex命令。该命令用一个字符x代替一系列命令commands。 如果不带参数,则显示当前定义的所有宏。
:unmap x :取消宏x。
初始化文件 —— .exrc,.vimrc
使用双引号(")注释说明信息,vi将读到的每一行都当成ex命令,所以可以省略开头的冒号。
VIM新添加的功能:
^[ :进入命令模式
vim中新引入了两种模式,一种是可视模式(visual mode),另一种是选择模式(select mode)。
v :进入的字符可视化模式(Characterwise visual mode)。文本选择是以字符为单位的
V : 进入的行可视化模式(Linewise visual mode)。文本选择是以行为单位的。
^V : CRTL+v: 进入的块可视化模式(Blockwise visual mode)。可以选择一个矩形内的文本。
选择模式是另一种的可视化模式,她可以允许我们对选中的文本进行快速的删除和替换操作。我们可以高亮显示文本,然后用Backspace来删除这段文本;也可以高亮显示文本,然后用输入的内容来替换这些文本。
那么选择模式和可视化模式又有何区别呢?在可视化模式下,我们可以高亮显示选中的文本,然后执行命令操作。换句话说,我们要用命令来结束可视化模式。而在选择模式下,命令仅限于backspace和可打印的字符(用于替换操作)。因为不需要输入命令,所以我们的操作变得更为简单,但同时它也有着很多的限制。
gh :进入选择模式。
gH :进入行选择模式。
g^H :进入块选择模式。
在选择模式下移动光标比正常模式下要显得困难一些。因为输入任何可打印字符,Vim就会删掉我们选中的文本并进入插入状态。所以要选择文本我们只好使用方向键、CTRL以及功能键。
vim中新添加的命令:
在输入模式下:
^N: 向下匹配单词。
^P:向上匹配单词。
^X:寻找匹配。
^O : 暂时进入命令模式
命令模式下:
gUw: 将光标到单词末尾改成大写。
guw:将光标到单词末尾改成小写。
代码跳转:
[{ : 跳转到当前代码块的开头
]} : 跳转到当前代码块的末尾
[[ :向前查找一个函数的开始
]] :向后查找一个函数的开始
][ :向前查找一个函数的结尾
[] :向后查找一个函数的结尾
{ :前一个空白行上
} :后一个空白行上
# :到与当前词相同的上一个单词上
* :到与当前词相同的下一个单词上
%: 让光标从当前所在的括号跳到与它匹配的括号上去
^] :跳到tags定义的地方
^T :返回调用tag的地方
代码折叠:
zc: 折叠代码
zC: 对所在范围内所有嵌套的折叠点进行折叠
zo: 打开折叠
zO: 对所在范围内所有嵌套的折叠点展开
zM: 折叠所有代码
zR: 展开所有代码折叠
代码缩进:
>> 右缩进 << 左缩进,注意n<< 或 n>>是缩进多行,如4>>
==: 自动缩进当前行
gg=G: 格式化全文
gq:格式化命令
g^G: 显示当前文件的总行数和总字符数。
可视模式下: