Vim 学习笔记:移动和编辑

Vim 入门及简单使用,包括简单介绍 Vim 模式,移动,和编辑命令。

这篇文档相较于之前的入门教程会相对比较丰富,建议入门后再阅读。可以了解到在基础操作上一些能够快速提高效率的方法。

模式切换 Change between modes

如果你不知道 Vim 的各种模式,可以参考 Vim 模式

Insert -> Normal : ESC/Ctrl-[
Insert -> Command : (Insert -> Normal) -> :

Normal -> Command : :
Normal -> Insert : iIsScCoO
Command -> Normal : Enter

插入模式

i       进入 insert mode,在光标为之前进入插入模式
I       行首非空字符前插入 , I 等同于 `^i`
s       删除光标下字符,并进入 insert mode, 等同于 `cl`
S       删除光标所在一行,并进入 insert mode 行首 , 等同于 `^C`
a       光标之后进入 insert mode
A       光标移动到行尾并进入 insert mode , 等同于 `$a`
o       在光标下一行插入一行,并进入 insert mode , 等同于 `A<CR>`
O       在光标上一行插入新行,并进入 insert mode , O 等同于 `ko`
C       删除光标及光标后到行尾的内容,并进入 insert mode , C 其实等同于 `c$`
cc      删除行,并进入插入模式
gi      进入上一次推出插入模式时位置
ESC     退出插入模式
Ctrl-[  退出插入模式

下面这些命令的一大特征是都会进入插入模式

替换模式

按如下两个按键进入替换模式:

r replace the letter under cursor
R replace under cursor till you press <Esc>

简单移动

简单的移动

    k
    ^
h <   > l
    v
    j

上面显示的 hjkl 都是光标移动上下左右一格,下面的键能够让光标移动句子或者段落

)       向后文移动一个句子,句号分割
(       向前文移动一个句子
}       向后文移动到一个段落,空行分割
{       向前文移动一个段落
<Enter> 移动到下一行首个非空字符
+       同回车
-       移动到上一行首个非空字符

高效移动

在 Vim 中,Word 有两种含义,开始我也没搞明白,过了很久才渐渐明白。广义的 WORD 可以是任何两个空格之间的内容,比如 this is a word ,就是四个大写的 WORD 。侠义的 word ,英文单词、标点符号和非字母字符都被当成一个字。如$、%、^、&、*、(、)、-、+、{、}、[、]、~、|、\、<、>、/等,均被当成是一个字。

举例说明,比如 sub-directory 就是两个 word 但是是一个 WORD 。关于 word 的参考可以见 word ,一般情况下记住大写的 WORD 是空格分割的词就行。

Vim 中使用大写命令一般将字作为广义,小写命令就是作为侠义对待。命令都是成对出现,w 和 W,b 和 B,e 和 E:

w 词向后移动
W WORD is splited by space
b 词向前移动
B WORD 向前移动
e 移下一个单词词末
ge 前一个单词词末
E 如果光标起始位置处于字内(即非字尾处),则该命令将把光标移到本字字尾;如果光标起始位置处于字尾,则该命令将把光标移动到下一个字的字尾。
0 光标移动到行首
^ 光标移动到行首**非空白字符**
$ 光标移动到行尾非空白字符
+ 光标移动到下一行非空白字符首字

以下命令可以用来翻页

Ctrl-f  下一页
Ctrl-b  上一页
Ctrl-d  下半页
Ctrl-u  上半页

下面三个按键是在不移动文档的情况下将光标快速移动到文档的开始中间和结尾

H       Move to first letter on top of screen
M 		Move to first letter on middle of screen
L 		Move to first letter on bottom of screen

与之对应的是 zt, zz, zb 分别表示将当前光标所在行移动到 top, middle 和 bottom.

另外还有两个个人不怎么喜欢使用的

Ctrl-Y/Ctrl-E

在不移动光标的情况下,将文档向上或者向下移动一行。

行内移动 move inline

f{x}  向后查找本行中的字符 x, 比如想要移动到下一个双引号时,可以使用 `f"` 来实现行内快速移动
2f{x} 向后跳转到 第二个 x 字符,2 可以替换为任意数字
F{x}   向前面查找 x
t{x}  跳转到下一个为 x 的字符前一位
T{x}  跳转到上一个为 x 的字符的后一位
;   跳转到下一个 f/t 搜索结果
,   跳转到上一个 f/t 搜索结果
g_  光标移动到行尾,包括空白字符

指定移动

nG      跳转到第 n 行
:n      跳转到第 n 行
10%     跳转到文件 10% 行
10|     跳转到当前行 10 列

复制粘贴 Copy/Paste

p   光标之后粘贴 (p)aste
P   paste before the cursor
yy  复制当前行
y   Yank 复制。Example: yw (yank word) 光标停留到词第一个字母上 yw 复制单词
y0  copy the data from cursor to begining of the line
y$  copy the data from cursor to end of the line

删除 delete

x   删除光标下单个字符,将其放到粘贴板,剪切
X   向前删除一个字符,相当于 Backspace
dd  删除光标所在一行,并把该行复制
dw  删除光标所在词 (d)elete (w)ord
d0  删除光标到该行最前
d^  删除光标到行首非空白字符
d$  删除光标到该行最后
D   相当于 d$
J   删除光标所在行的换行符
Ctrl-w      删除光标前一个单词

剪切 x ,删除 dd ,dw 用的情况还挺多的。

在插入模式下删除

在 Vim 插入模式下可以使用下面的命令来删除字符、单词或者行

Ctrl-h    向前删除一个字符
Ctrl-w 	  先前删除一个单词
Ctrl-u    删除至行首
Ctrl-k    删除至行尾

这 bash 的快捷键一致

撤销 / 重做 redo

u   撤销上一次编辑 undo
Ctrl-r redo

搜索与替换 search replace

/pattern  - 正向搜索,从光标处开始向文件末搜索
?pattern  - 反向搜索,从光标处开始向文件首搜索
n  - 下一个,往下执行搜索命令
N  - 上一个
*  - Word under cursor - forward (bounded)
g* - Word under cursor - forward (unbounded) 不包含单词边界 `\<\>`
#  - Word under cursor - backward (bounded)
g# - Word under cursor - backward (unbounded)
:s/p1/p2/g - 将当前行中所有 p1 均用 p2 替代
:n1, n2s/p1/p2/g - 将第 n1 至 n2 行中所有 p1 均用 p2 替代
:g/p1/s//p2/g - 将文件中所有 p1 均用 p2 替换

Load/Save/Quit/Change File

:e <path/to/file> open file
:w save
:saveas <path/to/file> save to <path/to/file>
:x, ZZ or :wq save and quit (:x only save if necessary)
:q! quit without saving. :qa! to quit even if there are modified hidden buffers
:q! 放弃修改之后可用 :e! 恢复修改 :e! 为放弃为保存的修改

Other

gg     移动光标到文件开头
G      移动光标到文件末尾
Ctrl-O 跳转到上一个位置
Ctrl-T 标签退栈
g; / g, 	上一个 / 下一个修改点

参考


2015-05-06 vim , linux , command , editor

Vim 中不同模式间的切换

之前的一篇文章介绍了 Vim 的多模式,这篇文章重点来讲一讲如何在这些模式之间随心的切换。

Normal - Insert

Normal - Visual

在普通模式和可视模式之间切换。

Normal -> Visual

上一篇文章 提到过 v 是通向可视模式的大门,记住 v

普通模式切换到可视模式可以有如下的方式:

命令 作用
v 字符可视模式
V 行可视模式
Ctrl-v 块可视模式
gv 重选上一次高亮区域

Visual -> Normal

如何从可视模式回到普通模式

命令 作用
Esc 最常用的回到普通模式
Ctrl-[ 回到普通模式
v / V / Ctrl-v 在对应的模式下回到普通模式

Visual -> Visual

如果想要在可视模式不同状态间调整,比如想要将字可视模式切换成行可视模式,那么直接按下对应的 V 即可。

切换选区的活动端

高亮选区的范围由两个端点决定,可以使用 o 来切换活动端点。比如说有种情况,选择选区时,发现选区开始位置不对,这时不用退出可视模式,从头开始,只需要按 o,将活动端点切换为开始端点,重新调整选区即可。

这个时候有人就要问了,对于字可视模式和行可视模式比较好理解,只有两个端点,可视如果是快可视模式,那么对于框有四个点,这个时候就需要依靠 O 来切换,在块可视模式中 O 会移动到同一行的另一端。而其他情况 Oo 一样。

Visual - Insert

可视模式和插入模式之间切换,绝大多数情况都是从 Visual 模式切换到 Insert 模式,做一些任务之后在回去。似乎很少遇到直接从 Insert 模式中切到 Visual 模式的,所以这里就直接介绍一下从 Visual 模式切换到 Insert 模式。

和普通模式切换到 Insert 模式类似,在可视模式下也可以直接使用如下按键:

命令 作用
c 删除选区内容并进入插入模式
I / A 在行可视,块可视模式下跳转到行首行尾

Ex

在任何模式下输入 : 就会进入 Ex 命令模式。


2015-05-05 vim , linux , editor , linux , vim-mode

如何写单测

单元测试是白盒测试,又被称为模块测试,是最小的测试单元。

单测应该做到:

  • 一次检测一个方法
  • 提供方法所需的参数
  • 验证结果的准确性

Why

为什么需要单测

  • 正确性保证
  • 提高代码质量,高内聚,低耦合
  • 代码重构时回归验证

测试内容

测试的内容可以包括

  • 模块接口
  • 局部数据结构
  • 分支路径
  • 错误处理
  • 边界测试

评价测试的指标,覆盖范围,是否测试代码覆盖了基本表达语句,基本逻辑块。

  • 语句覆盖,每一个基本语句是否被覆盖
  • 判定覆盖,分支的每一个路径是否都被覆盖
  • 循环覆盖,循环体,0,1,多次是否都被覆盖

Mock 工具

Mock 使用场景

  • 依赖外部调用
  • DAO 层,数据库等底层存储调用
  • 系统间异步通知
  • 应用中类(Abstract,final,static),接口等

Mock 工具工作的过程

  • Record 过程,准备数据阶段,创建依赖的 Class,Interface 后者 Method,模拟返回的数据,耗时,调用次数等等
  • Replay 阶段,调用被测试代码,执行测试,期间 Invoke 上一阶段准备的 Mock 对象或者方法
  • Verify 阶段,验证调用是否正确,Mock 方法调用次数,顺序等等

目前比较流行的 Mock 工具有 EasyMock,jMock,Mockito,Unitils,Mock,PowerMock,JMockit 等等

Best practices

Unit test 执行前后不能对环境造成污染,避免写有副作用的 TestCase

自我清理:

  • 文件
  • H2 内存数据库
  • MySQL 事务回滚 @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)

保持效率

  • Unit test 中不要 Sleep
  • 对于异步操作,用 Future 等待结果或者使用 CountDownLatch 通知

测试粒度

  • 测试尽量小,执行速度快
  • 一次测试一个对象,出现问题容易排查
  • 测试方法应当尽量简单明了

结果验证

  • 尽量使用 Unit test 提供的 assert/fail 方法

保持独立

  • 执行顺序不确定,因此测试用例之间一定要保持完全独立,不能相互依赖。

仅测试公有接口

  • 测试类公有 API
  • 一些测试工具允许测试类私有成员,应该尽量避免测试私有成员,否则会让测试变得繁琐难以维护
  • 如果私有成员需要进行直接测试,可以考虑重构到工具类公有方法中

覆盖边界值

– 确保参数边界值均被覆盖。对于数字,测试负数、 0 、正数、最小值、最大值、 NaN (非数字)、无穷大等 – 对于字符串,测试空字符串、单字符、非 ASCII 字符串、多字节字符串等 – 对于集合类型,测试空、 1 、第一个、最后一个等 – 对于日期,测试 1 月 1 号、 2 月 29 号、 12 月 31 号等

编写反向测试

  • 刻意编写问题代码,验证鲁棒性和是否能够正确处理
  • 异常处理方法

单元测试无法证明代码正确性,一个失败的单测表明代码可能有错误,但一个成功的单测什么也不能证明。

reference


2015-05-05 unit-test , junit , java , testing

Vim插件Vundle

简单介绍

Code Rush推荐,之后又陆陆续续看到很多在使用这款插件,所以在入门插件的时候就第一个安装了此插件,VIM如果不依靠插件来增强功能可谓鸡肋。而VIM提供的插件又很多,新手可能无从下手。幸好让我接触到了这个Vundle插件,Vundle用来安装,管理其他插件,这样以后安装插件卸载插件的问题就迎刃而解了。用Vundle管理插件有以下好处:

  • 自动下载安装插件
  • 自动更新插件
  • 只需要保存一份配置文件即可在新环境下安装所有插件
  • 自动清理没用的插件

安装

下载地址

https://github.com/gmarik/Vundle.vim

Mac和Linux安装

  1. 安装git客户端 Mac和Linux一般默认已经安装

  2. 下载并安装Vundle

     git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim
    
  3. vimrc配置

    把以下的配置放到vimrc最前面

     set nocompatible              " be iMproved, required
     filetype off                  " required
    
     " set the runtime path to include Vundle and initialize
     set rtp+=~/.vim/bundle/Vundle.vim
     call vundle#begin()
     " alternatively, pass a path where Vundle should install plugins
     "call vundle#begin('~/some/path/here')
    
     " let Vundle manage Vundle, required
     Plugin 'gmarik/Vundle.vim'
    
     " The following are examples of different formats supported.
     " Keep Plugin commands between vundle#begin/end.
     " plugin on GitHub repo
     Plugin 'tpope/vim-fugitive'
     " plugin from http://vim-scripts.org/vim/scripts.html
     Plugin 'L9'
     " Git plugin not hosted on GitHub
     Plugin 'git://git.wincent.com/command-t.git'
     " git repos on your local machine (i.e. when working on your own plugin)
     Plugin 'file:///home/gmarik/path/to/plugin'
     " The sparkup vim script is in a subdirectory of this repo called vim.
     " Pass the path to set the runtimepath properly.
     Plugin 'rstacruz/sparkup', {'rtp': 'vim/'}
     " Avoid a name conflict with L9
     Plugin 'user/L9', {'name': 'newL9'}
    
     " All of your Plugins must be added before the following line
     call vundle#end()            " required
     filetype plugin indent on    " required
     " To ignore plugin indent changes, instead use:
     "filetype plugin on
     "
     " Brief help
     " :PluginList       - lists configured plugins
     " :PluginInstall    - installs plugins; append `!` to update or just :PluginUpdate
     " :PluginSearch foo - searches for foo; append `!` to refresh local cache
     " :PluginClean      - confirms removal of unused plugins; append `!` to auto-approve removal
     "
     " see :h vundle for more details or wiki for FAQ
     " Put your non-Plugin stuff after this line
    
  4. 安装插件

    启动vim,并运行:PluginInstall

Windows下安装

查看官方教程,官方的教程有点问题,完全按照所写配置并不能成功。

vim74     #主程序目录 对应变量 $VIMRUNTIME
vimfiles  #配置文件目录 对应变量 $VIM	
  1. 同样需要Git,并且需要Curl

  2. 下载安装msysgit,add Path to your environment.安装过程中选择Run git from Windows command prompt option安装完成之后在终端运行git --version,如果出现类似以下情况即可:

     C:\> git --version
     git version 1.7.4.msysgit.0
    
  3. 设置Curl

    以下内容保存成curl.cmd,并存到msysgit安装目录中C:\Program Files\Git\cmd\curl.cmd,在终端运行curl --version出现以下类似内容即可:

     C:\> curl --version
     curl 7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8k zlib/1.2.3
     Protocols: dict file ftp ftps http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
     Features: Largefile NTLM SSL SSPI libz
    
  4. 因为Windows下和mac,linux环境不同,vim的配置地址也不同,所以git clone到的目录如下:

     git clone https://github.com/gmarik/Vundle.vim.git vimfiles/bundle/Vundle.vim
    
  5. _vimrc

    需要将Mac和Linux中相应位置代码修改成如下代码:

     " 配置同Mac,只需要按照下面修改rtp的路径即可
     set rtp+=$VIM/vimfiles/bundle/Vundle.vim/
     let path='$VIM/vimfiles/bundle'
     call vundle#rc(path)
    

使用

使用方法很简单,只需3步使新插件生效即可

  1. 将目标插件配置进vimrc或vundle_vimrc
  2. 执行:PluginInstall
  3. 重启

常用命令

:PluginList       - 枚举已安装的插件列表
:PluginInstall    - 安装插件或者后面加上'!'更新
:PluginUpdate     - 更新插件 同 :PluginInstall!
:PluginSearch foo - 查找插件。例如查找名称为foo的插件。或者后面加'!'更新本地缓存
:PluginClean      - 清理无用插件或者后面加'!'自动清理

更多使用方法查看帮助 :h vundle

参考:


2015-05-04 vim , vim-plugin , vundle

Ubuntu 下安装 java 及问题配置

记录一下

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update

或者下载 Oracle 的版本

wget -c --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz

http://download.oracle.com/otn-pub/java/jdk/8u144-b01/090f390dda5b47b9b721c7dfaa008135/jdk-8u144-linux-x64.tar.gz

切换 java 版本

我们知道默认情况下我们会配置 JAVA_HOME 的位置,但是有些情况下需要依赖 java 运行的应用可能也会找到其他的系统自带的 JAVA 版本。

默认情况下 系统会去 /usr/bin/java 找对应的 Java 版本,可以使用

sudo update-alternatives --list java

如果新安装 Java 版本可以使用

sudo udpate-alternatives --install /usr/bin/java java /path/to/java 1

最后使用

sudo update-alternatives --config java

选择系统要优先手动选择的 java 版本。


2015-05-02 java , jdk , apt-get

Vim 多模式介绍

Vim 是一种多模式的编辑器,不同于一般的编辑器进入便是编辑模式,可以在编辑模式下对文本进行各种编辑,Vim 进入之后是在普通模式 (Normal mode) 下,需要通过不同的按键进入不同的编辑模式。在《Vim 使用技巧》这本书中,作者有一个非常贴切的比喻,如果画布之于画家,那么 Vim 之于程序员,画家在画布上真正作画的时间必然不应该,也不会超过一半时间,在真正落笔之前,画家可能会构图,调整光线,配置画笔颜色等等操作,等一切准备就绪之后再在画布上作画。Vim 这款编辑器的原理也大致如此,大部分的时间我们都会在 normal mode(普通模式) 下,进行浏览,移动光标等等,而真正要进入编辑的时候再切到 insert mode,进行文本编辑。

当然 Vim 还有其他,比如可视模式,选择模式,命令模式等等其他模式,在不同的场合使用。当你熟悉了这些常用的编辑模式之后,可能就再也回不到无模式的编辑了。因为这些模式的划分,使得不同模式下专注于该模式的使用方式,结果便使得每一种模式下对文本编辑的效率都要远远超出于无模式编辑器。

基本模式

普通模式 Normal mode

和大多数无模式编辑器不同,Vim 默认启动就是普通模式,在该模式下不能够像普通编辑器一样可以插入编辑。在普通模式中,用户可以执行一般的编辑器命令,比如移动光标,删除文本等等。这也是 Vim 启动后的默认模式。这正好和许多新用户期待的操作方式相反 (大多数编辑器默认模式为插入模式)。

在 《Practical Vim》书中,作者将 Vim 比喻为画板,使用 Vim 的用户比喻为画家,你想想画家用了多长时间用笔刷在画板上画画?画家可能在落笔之前会花很长时间研究绘画的对象,调整光线,混合颜料,等等,当真正落笔的时候也不一定是使用画笔,也可能使用调色刀来给画面增加纹理,或者使用棉棒来优化画面。画家并不依赖着画笔休息,对于 Vim 同理,画家花费零碎的时间绘画,programmers 同样花费零散的时间编写代码。更多的时间用来思考,阅读和浏览。当真正需要调整代码时,也不一定是插入,也可能是重新格式化代码,复制,移动,删除等等,在 Normal Mode 下有很多方法可以使用 (at our disposal)。

Vim 强大的编辑能力中很大部分是来自其普通模式命令。普通模式命令往往需要一个操作符结尾。例如普通模式命令”dd”删除当前行,但是第一个”d”的后面可以跟另外的移动命令来代替第二个”d”,比如用移动到下一行的”j”键就可以删除当前行和下一行。另外还可以指定命令重复次 数,”2dd”(重复”dd”两次),和”dj”的效果是一样的。学习了各种各样的文本间移动/跳转的命令和其他的普通模式的编辑命令,并且能够灵活组合使用的话,能够比那些没有模式的编辑器更加高效的进行文本编辑。

在普通模式中,有很多方法可以进入插入模式。比较普通的方式是按”a”(append/追加,光标移动到行尾并进入插入模式)键或者直接使用”i”(insert/插入)键进入。

插入模式 Insert mode

插入模式最好理解,在这个模式下用户输入的任何字符都会直接出现在编辑器中,这是大多数文本编辑器的默认模式,也是大多数新用户希望文本编辑器编辑过程中保持的模式。

在普通模式下按下 “i” 键进入,在这个模式中,大多数按键都会向文本缓冲中插入文本。但是 Vim 的设计哲学告诉我们,只有在真正输入文本的时候进入该模式,否则立即按下 ESC 退出到普通模式。

在插入模式中,可以按 ESC 键回到普通模式。

从普通模式切换到插入模式有非常多的方式,最简单最直白的便是上面提到的 i 键,直接进入插入模式,但实际上你可以用 A 将光标直接跳到行尾,再进入插入模式,或者使用 I 跳转到行首再直接进入插入模式。在之后的文章中会提到更多的切换方式,这里只需要记住从普通模式切换到插入模式的方式有非常多样的选择,如何选择切换的方式也会非常重要。

可视模式 Visual mode

Vim 的可视模式让用户可以选择一些文本,并在上面进行一些操作。这个模式大部分的编辑器也同样拥有,但是 Vim 的可视模式则有一些非常的不同,Vim 拥有三种不同类型的 Visual mode,分别操作字符,行,和块。

在普通模式下按下 “v” 键进入,使用“V”可按行选择,这个模式与普通模式比较相似。但是移动命令会扩大高亮的文本区域。高亮区域可以是字符、行或者是一块文本。当执行一个非移动命令时,命令会被执行到 这块高亮的区域上。Vim 的”文本对象”也能和移动命令一样用在这个模式中。

  • v命令进入的字符可视化模式(character-wise visual mode)。文本选择是以字符为单位的。
  • V命令进入的行可视化模式(line-wise visual mode)。文本选择是以行为单位的。
  • Ctrl-V进入的块可视化模式(block-wise visual mode)。可以选择一个矩形内的文本。(注意:在 Windows 中,Ctrl-V可能已经被影射为粘贴操作,可以使用Ctrl-Q进入块可视化模式。)

简单的记住,v 是通向可视模式的大门,上面的每一个操作都可以和 count 结合使用,比如要选择 104 行内容,可以直接 104V

  • [count]v
  • [count]V
  • [count]Ctrl-v

另外一相关的是 gv 表示选择上一次选中的区域。因此也能看到 v 键是 Visual mode 的入口了。可视模式一般有一个固定的开始,一个可以自由移动的结束符,在 Visual mode 中可以使用 o 来在开头和结尾之间切换。

在 Vim 中使用如下命令查看更多官方帮助

:h 04.4

选择模式 Select mode

这个模式和无模式编辑器的行为比较相似(Windows 标准文本控件的方式)选中内容之后敲击其他按键会直接删除选中内容并输入敲击的内容。选择模式与可视模式相似,这个模式中,可以用鼠标或者光标键高亮选择文本,不过输入任何字符的,Vim 会用这个字符替换选择的高亮文本块,并且自动进入插入模式。选择模式更多在 MS-Windows 中用到,其他系统如需启动选择模式,首先需要激活:

:set selectmode+=mouse

如果熟悉 Vim 的模式特征,那么应该很少会用到选择模式,这一模式的存在,只是为了迎合那些想要让 Vim 更像其他编辑器的用户。

在 Vim 中使用如下命令查看更多官方帮助

:h 09.4

选择模式和可视模式在状态栏提示符有差别,可视模式会显示 -- VISUAL -- 而选择模式则是 -- SELECT --。 在这两个模式下可以使用 Ctrl-g 来在可视模式和选择模式之间切换,切换的时候能看到下方 -- VISUAL ---- SELECT -- 切换。

命令行模式 Command line mode

Vim 可以追溯到 Vi,也就是那个时候产生了现在的多模式的编辑器。而依次追寻下去,vi 可以追溯到他的祖先,行编辑器 ex,所以这也就是为什么现在 Vim 中还保留这 ex 命令。那些原始 Unix 文本编辑器的 DNA 被保留到了现代的 Vim 中。对于一些面向行的编辑任务, Ex 命令依然是执行这些任务的最好工具。

因为历史原因,在命令行模式中执行的命令又被称为 Ex 命令。Ex 命令可以包括搜索,或者一个表达式,或者操作 buffer 等等。

在命令行模式中可以输入会被解释成并执行的文本。例如执行命令(:键),搜索(/?键)或者过滤命令(!键)。在命令执行之 后,Vim 返回到命令行模式之前的模式,通常是普通模式。当输入 : 之后 Vim 就进入了 Command Line mode。

Ex Commands That Operate on the Text in a Buffer

命令 解释
:[range]delete [x] 删除指定行到寄存器 x 中
:[range]yank [x] 复制指定行到寄存器 x 中
:[line]put [x] 放置寄存器 x 中内容到指定行后
:[range]copy {address} 复制指定行到 address 行后
:[range]move {address} 移动指定行到 address 行后
:[range]join 连接指定行
:[range]normal {commands} 在指定行执行 normal 模式下命令
:[range]substitude/{pattern}/{string}/[flags] 在指定行中用 string 替换匹配 pattern 的内容
:[range]global/{pattern}/[cmd] 在匹配 pattern 的所有行中执行 Ex 命令 cmd

其他

  • 读写文件 :edit:write
  • 创建新标签页 :tabnew
  • 分割窗口 :split
  • 操作参数列表 :prev/:next
  • 缓冲区列表 :bprev/:bnext
  • 替换,比如使用 :%s/a/b/g 将文本中所有的 a 替换成 b。
  • 搜索 /abc 来搜索文本中的 abc 字符串

Vim 为几乎所有功能功能都提供了 Ex 命令,参考 :h ex-cmd-index点击查看所有 Ex 命令

Ex 模式

这和命令行模式比较相似,在使用”:visual”命令离开 Ex 模式前,可以一次执行多条命令。我至今没用过,如果需要 Google 关键词:Vim Ex 模式。

普通模式下按 Q 进入 Ex 模式,多行 Command Line 模式

派生模式

Normal, Insert, Visual 模式都是显而易见,顾名思义的。但是 Vim 中存在一些模式经常会被忽视,在日常使用中可能经常会用到,经常一闪而过,所以我们可能根本没有意识到。

操作符等待模式 Operator-pending mode

比如操作符等待模式,比如当我们执行命令 dw 时,在按下 dw 两个按键中间短暂的时间就是操作符等待模式。

所以操作符等待模式指的是普通模式中,执行一个操作命令后 Vim 等待一个”动作”来完成这个命令这个时间的模式。当我们把 Vim 想象为有限状态机,那么操作符等待模式就是在只接受 motion 命令的那个状态。当 operator 命令被按下该模式就被激活,此时没有任何事情发生,直到提供一个 motion,完成一整个操作。

这边提及的 Operator 和 Motion 在后面的文章中会经常提及,这边先简单介绍,Vim 支持命令组合,比如 daw 表示的是 delete a word 那么这里的 d 是 Operator 而 aw 是 Motion

Operator + Motion = Action

Vim 自带 Operator

Vim 也支持在操作符等待模式中使用”文本对象”作为动作, 包括”aw”一个单词(a word)、”as”一个句子(a sentence)、”ap”一个段落(a paragraph)等等。

比如,在普通模式下”d2as”删除当前和下一个句子。在可视模式下”apU”把当前段落所有字母大写。

有一些 Operator 有多个按键比如 g 开头 z 开头 Ctrl-W[ 这些按键第一个按键不会进入操作符等待模式。

插入普通模式 Insert Normal mode

对于初学者来说,经常在切换模式间变得疲惫,但是通过练习一切都会变得自然。但是 Vim 的模式在一种特殊场景下会显得笨拙:当在插入模式下,想要执行一条 Normal 模式命令,然后继续在 Insert 模式下编辑。Vim 提供了一个利落的解决方法来消除这一类的问题,这就是插入普通模式 Insert Normal mode。

插入普通模式是一种特殊的 Normal mode,这种模式下只给我们执行一次命令的机会,执行结束后就返回到 Insert mode。这个模式是触发的条件:在插入模式下按下 Ctrl-o 键的时候进入,这时暂时进入普通模式,执行完一个命令之后,Vim 返回插入模式

插入可视模式

这个模式是在插入模式下按下 ctrl-o 键并且开始一个可视选择的时候开始。在可视区域选择取消的时候,Vim 返回插入模式。

插入选择模式

通常这个模式由插入模式下鼠标拖拽或者 shift 方向键来进入。当选择区域取消的时候,Vim 返回插入模式。

替换模式

这是一个特殊的插入模式,在这个模式中可以做和插入模式一样的操作,但是每个输入的字符都会覆盖文本缓冲中已经存在的字符。在普通模式下按”R”键进入。

vim key command


2015-05-01 vim , linux , editor , vim-mode

Vim字符编码及中文菜单乱码

vim经常遇到文件乱码的情况,很多的文章都只是解决了作者遇到的乱码问题,不同的使用者由于环境不一样,参考之后,反而更加混淆和复杂。

其实vim乱码是与系统环境非常相关的,一味执着于修改vim的配置而不知道分析系统的实际环境,往往导致混淆,本文从原理分析vim编码的设计和乱码原因,帮助所有的用户解决vim的乱码。

vim为何会出现乱码:

  1. 首先是输入,vim 以错误的格式解析文件,比如原本是utf-8,但以ansi解析,那必然是乱码了。
  2. 然后是处理,vim 以错误的格式处理文件,比如原本是utf-8,但内部以 ansi 保存处理,导致乱码。
  3. 然后是输出,vim 输出显示的编码与系统不一致,也会乱码。
  4. 最后是写入,vim 回写文件与打开的不一致,造成编辑后文件乱码。

在 Linux 下需要考虑:

  1. Linux 默认支持的语系,/etc/sysconfig/i18n
  2. 终端 bash 的语系,与 $LANG 变量有关
  3. 再就是上面提到的文件编码有关

VIM编码相关选项

Vim 有四个跟字符编码方式有关的选项,encodingfileencodingfileencodingstermencoding (这些选项可能的取值请参考 Vim 在线帮助 :help encoding-names),它们的意义如下:

encoding

encoding(enc) : Vim 内部使用的字符编码方式,包括 Vim 的 buffer (缓冲区)、寄存器中字符串、菜单文本、消息文本等。用户手册上建议只在 .vimrc 中改变它的值,事实上似乎也只有在 .vimrc 中改变它的值才有意义。Vim 读取文件之后,但并不以读取文件的编码来处理,而是会转换成内部编码的格式。这个编码默认是系统 locale 决定,一般与操作系统相关,linux下utf-8居多,中文windows下则是gbk。可以使用 :set enc 来查看当前 enc 设置

fileencoding

fileencoding(fenc) : 用于配置打开文件和保存文件的编码,fenc 是当前缓冲区文件自身的编码。从磁盘读取文件, Vim 会对文件编码检查,如果文件的编码与 Vim 内部编码(enc) 不同, Vim 会对文本做转码。当 Vim 向磁盘写文件时, enc 与 fenc 不一样, Vim 会转码成 fenc 编码保存文件。

该设置只能有一个值,只适合少数文件都是同种编码的环境

fileencodings

fileencodings(fencs): 这是一个字符编码的列表,Vim 启动时会按照它所列出的字符编码方式逐一探测即将打开的文件的字符编码方式,并且将 fileencoding 设置为最终探测到的字符编码方式。因此最好将 Unicode 编码方式放到这个列表的最前面,将拉丁语系编码方式 latin1 放到最后面。从名字上看就知道是fileencoding的增强版,可以配置多种不同的编码,常见的配置为,配置好之后,列表中的文本编码只要合法,都能被 Vim 正确的读取。

termencoding

termencoding(tenc): Vim 所工作的终端 (或者 Windows 的 Console 窗口) 的字符编码方式,或者说是 Vim 用于屏幕显示时的编码。这个选项在 Windows 下对我们常用的 GUI 模式的 gVim 无效,而对 Console 模式的 Vim 而言就是 Windows 控制台的代码页,并且通常我们不需要改变它。Vim 输出的编码,输出指输出到操作系统或命令终端等,默认与操作系统的语言编码一致,如果使用linux命令终端,建议终端和linux系统配置相同的编码,然后配置相同的termencoding,否则顾全了vim就顾不上shell,不过如果shell不存在中文名文件,则配置终端和termencoding一致即可,对于windows,能自动的识别gbk和utf-8,不用特殊配置。

fileformats

fileformats,用于区分操作系统,主要是回车\r\n的区别,fileformats选项,用于处理文件格式问题。以下命令,告诉 Vim 将UNIX文件格式做为第一选择,而将MS-DOS的文件格式做为第二选择:(换行方式 在早期的打印机时代,开始新的一行要占用两个字符的时间。如果到了一行的结尾处,你要快速回到新的一行的开头,需要打印针头在纸面上飞快地掠过,常常会在纸面上留下污点。解决这个问题的办法就是,用两个字符:一个字符来移到第一列,另一个字符来新增一行。计算机产生以后,存储较为昂贵,在如何解决回车换行这个老问题上,人们产生了不同的意见。UNIX人认为在到达一行的结尾时新增一行 (LF),而Mac人则认同 (CR)的解决办法,MS则坚持古老的 (CRLF)的方法。这就意味着如果你将一个文件从一个系统转移到另一个系统,就面临着回车换行的问题。而 Vim 编辑器则会自动的认出这种文件格式方面的区别,并做出相应处理。)

set fileformats=unix,dos

VIM 多字符编码方式工作流程

再记录一下,Vim 的多字符编码方式支持是如何工作的:

  1. Vim 启动,根据 .vimrc 中设置的 encoding 的值来设置 buffer、菜单文本、消息文的字符编码方式。
  2. 读取需要编辑的文件,根据 fileencodings 中列出的字符编码方式逐一探测该文件编码方式。并设置 fileencoding 为探测到看起来是正确的字符编码方式,如果没有找到合适的编码,就用latin-1(ASCII)编码打开。
  3. 对比 fileencoding 和 encoding 的值,若不同则调用 iconv 将文件内容转换为 encoding 所描述的字符编码方式,并且把转换后的内容放到为此文件开辟的 buffer 里,此时我们就可以开始编辑这个文件了。
  4. 编辑完成后保存文件时,再次对比 fileencoding 和 encoding 的值。若不同,再次调用 iconv 将即将保存的 buffer 中的文本转换为 fileencoding 所描述的字符编码方式,并保存到指定的文件中。

由于 Unicode 能够包含几乎所有的语言的字符,而且 Unicode 的 UTF-8 编码方式又是非常具有性价比的编码方式 (空间消耗比 UCS-2 小),因此建议 encoding 的值设置为 utf-8。这么做的另一个理由是 encoding 设置为 utf-8 时,Vim 自动探测文件的编码方式会更准确 (或许这个理由才是主要的 ;) 。我们在中文 Windows 里编辑的文件,为了兼顾与其他软件的兼容性,文件编码还是设置为 GB2312/GBK 比较合适,因此 fileencoding 建议设置为 chinese (chinese 是个别名,在 Unix 里表示 gb2312,在 Windows 里表示 cp936,也就是 GBK 的代码页)。

vimrc中设置

在分析了乱码原因,了解了vim编码的参数之后,就可以根据实际情况来配置了

  1. 分析文件编码,配置 Vim 文件文件解析编码fileencodings,让 Vim 能解析出来
  2. 分析系统编码,配置 Vim 内码encoding,如果linux系统语言为ansi,则必须配置内码,否则 Vim 无法处理中文,中文windows下 Vim 内码为gbk,但还是建议统一配置为utf-8
  3. 根据输出配置显示编码,linux系统如果使用了putty或者SecureCRT,需要注意配置termencoding和终端软件一致,windows系统比较少有终端软件,系统能自动解析gdb和utf-8,建议统一配置为utf-8

参考的 Vim 编码配置如下,linux 和 windows 配置相同,linux系统语言编码和ssh终端编码配置为utf-8,windows则不需要配置,即可正常的打开utf-8,gdk等编码的文件

" Vim 内部编码
set encoding=utf-8
"按照utf-8 without bom,utf-8,顺序识别打开文件
set fileencodings=ucs-bom,utf-8,gbk,gb2312,cp936,big5,gb18030,shift-jis,euc-jp,euc-kr,latin1

set fileencoding=utf-8

"防止菜单乱码
if(has("win32") || has("win64") || has("win95") || has("win16"))
	source $VIMRUNTIME/delmenu.vim
	source $VIMRUNTIME/menu.vim
	language messages zh_CN.utf-8
endif
"默认以双字节处理那些特殊字符
if v:lang =~? '^\(zh\)\|\(ja\)\|\(ko\)'
	set ambiwidth=double
endif

set nobomb "不自动设置字节序标记

参考:


2015-05-01 vim , linux , encode , fileencoding

开始使用 Vim 的方式

这是不是一篇 Vim 的教程,只是一个入门 Vim 的流程,如果你从未听说过 Vim,但是希望学习 Vim,那么可以继续往下看,如果想要了解 Vim 更多的功能可以参考博客中其他关于 Vim 的文章。

Brief Introduction

Vim 作为一款 Linux 下必备的编辑器,如果学会了使用,非常强大,但是不得不说 Vim 的入门实在是太困难了,他的学习曲线也会经过非常长的一段平缓期。当然如果只是简单的使用插入功能,i,进入插入模式,直接敲,敲完 esc 退出,再:wq保存退出,也就是最基本的入门了。当时如果想要尝试其他的功能,就不得不看文档,装插件,装配色方案,写 Vimrc 配置等等了。

其实很多 Vimer 都会对新手说一句看帮助文档,这句话对新手真的毫无用处,或许真的只有对 Vim 有了一定了解才能在文档的帮助下学到 Vim 更多的东西。文档一般都是大而全,有很多部分其实完全没有必要再新手阶段的时候就全部读完,而甚至有些命令,设置用了多年的 Vimer 都不会去接触一下。所以如何入门?首先要了解作为一个编辑器最基本的功能,写入,删除,修改,保存,编码,而对于 Vim,还有几大模式,移动光标,替换操作等等。

Vimtutor

在最短的时间内了解这个编辑器的基本功能,至少把他能够当成一个编辑器使,再不济能够直接使用键盘来浏览文件内容,对文件内容进行修改,删除,保存。当然在几十分钟内你可能要记住几十个命令,以及每个命令对应的操作。可能这对于很多新手来说需要锻炼一段时间才能记住,所以不要怕,用记事本,或者 Vim 记下来每个命令和对应的功能,之后不断的练习,很短的时间就能习惯这种操作。在习惯了之后就会发现再移动鼠标是多么的慢。当然你可能在 Vim 默认配置中有很多不太习惯的地方,把你那些不习惯记住,把那些你想要的功能一个一个记下来,在以后的学习中,我们来一一解决。

比如我在最初的时候觉得 j/k 在行之间移动,有些时候中文一行比较长,显示的时候跳跃了很多行,而是用 j/k 移动光标的时候在几行之间跳跃,让我很不习惯,当然这个在之后的学习中偶然看到了原来只要在 VimRC 中配置<map> j gj就能够用 j 来直接到下一行,即使这一行事实上是 Vim 中的一行。还有很多很多的问题,都在短短几天的时间内一一得到了解决。所以开始的时候用极短的时间略读一遍 Vimtutor 先熟悉。哦,对了,Vimtutor 在哪里,Windows 下是在 Vim 安装目录下Vimtutor.bat这个文件,双击运行,而 Linux 下直接终端运行 Vimtutor 即可。当然这一切都在 Vim 的帮助文档中写着了,你可以尝试在 Vim 普通模式下运行:help VimtutorVim 会把文档全部显示出来。

Vimrc

在熟悉了最基本的命令之后,你可以开始看文档,尝试修改 Vimrc 配置,当然如果你不想看英文文档,Vim 还是有中文文档 的。不想覆盖:help 的文档,直接下一个 PDF 的随时查看也挺好,在熟悉了一下命令之后,直接看英文的也就很快了。我的方法就是直接看别人的配置,去 Github 上面一搜,很多人把自己的配置都公开了,就去一条条试试那些命令,有什么作用,我自己能怎么修改,然后查文档,很快你自己熟悉的配置就有了。

Plugin

当然在熟悉 VimRC 配置之后,在随便哪个文件中只要运行:edit $MYVimRC就能够直接编辑 Vimrc 文件,我在网上看别人的博客,于是我也就用了很多人推荐的 Vundle 来管理我的插件,从此之后再不用下载,解压,复制,只需要修改 Vimrc 配置就能够安装插件,同样也只要保存一份配置文件就能够同步我的插件,这件事简直太棒了。当然最初安装 Vundle 这件事情是要你自己来的。直接去 Vundle 主页看吧。

colorscheme

或许在练习了 Vim 不久就会觉得 Vim 的颜色太单调,但是没关系,Vim 有很多很多的配色方案,只要你能找到总能找到自己喜欢的,我直接用了别人推荐的 molokai, 你也可以试试,下载 molokai.Vim 文件到 colors 目录下之后,在 Vimrc 中写入colorscheme molokai,就能使用这款配色了。当然你也能自己定义字体和字号,还有很多你能自己定义的东西等待发掘的。

附送两张图

vi tutorial

vi key command


2015-05-01 vim , tutorial , linux , editor

cloudup 尝鲜

应该是很久以前在听到一个韩国FM节目的时候遇到得这个网盘 Cloudup,当时直接能在网页上播放音频视频,所以觉得还不错,可是当我想去注册时才发现这个网站需要邀请才能注册,没办法只能申请邀请,于是等了很久很久之后,今天早上打开邮箱,官方终于邀请我去注册了。

官方的邮件也极其简单:

Thanks a million for joining the Cloudup wait list. You and your pals can now signup without waiting a minute longer!

Create your account now to start sharing files, links, pictures, gifs, videos, and documents instantly and beautifully with anyone. Just drag, drop, & stream.

Let me know if you have any questions, and have a wonderful week!

虽然简单但也把问题说的清清楚楚,这个社会已经没人不知道网盘服务了,所以也就么有必要解释,简单的说“能够分享文件,链接,图片,gifs,视频和文档”这也就够了。再把上传过程“drag,drop&stream”,分享界面beautiful说明白,真的足够了。其实我最关心的stream,很少网盘能够支持音视频直接串流的。

注册了账号体验了一把,界面清爽,操作简单,分享的链接漂亮,预览快速,支持直链,给我用也足够了。哦对了,这个网盘用item的数量来表示空间,至多能上传1000份文件,每个文件至多200M。我想也足够了呢。

你可以尝试我分享的Music:https://cloudup.com/cuP0Yl1BeGj

还有文档:https://cloudup.com/cSvQXovNXBx

最后你如果也想试试,我的邀请:https://cloudup.com/s/einverne-865

161011 更新

今天心血来潮,用 Cloudup 做个 Podcast 倒是很好的选择,查了这么久的 Podcast Hosting,各种收费,VPS,可是这个现成的 Cloudup 不是刚刚好么,1000个文件,想想都无法做到那么多,然后稳定性,经过这么多时间的观察,似乎这个已经是可以认可的了,并且这个云盘服务没有大规模扩张,一直保持着清爽的界面,真不知道后面是如何赚钱的,希望不会倒闭吧。


2015-04-30 products , cloudup , 网盘

每天学习一个命令:inxi 显示系统和硬件信息

inxi 是一个用来显示系统基本信息的脚本,输出结果经过整理适合打印到控制台或者 IRC,也非常适合在论坛中寻求技术支持时将结果贴出来。inxi 的输出信息包括系统硬件,CPU,驱动,Xorg,桌面环境,Kernel,GCC 版本,Processes,内存使用量,和其他一些信息。结果的输出颜色可以使用 -c 0 来禁用。

为了尽可能的保持基本的隐私和安全,inxi 自动过滤了一些敏感信息,包括网卡 mac 地址,WAN 和 LAN IP 地址,桌面用户名和其他一些内容。

安装

sudo apt-get install inxi

参数说明

-A          显示音频 声卡相关信息
-b          输出基本信息
-c [0-32]   不同的配色
-C          显示完整的 CPU 信息
-d          显示光驱和硬盘相关信息
-D          显示硬盘相关信息
-F          完整报告
-G          显卡
-i          WAN IP
-I          processes, uptime, memory, shell type etc
-m          RAM data
-M          machine data 主板,BIOS etc
-p          完整分区信息
-S          系统信息,hostname,kernel,桌面环境,发行版等等
-u          分区 UUID

使用实例

查看电脑硬件型号

inxi -F

监控 CPU 进程和内存使用

inxi -t c
inxi -t m
inxi -t cm

查看 CPU 温度和风扇速度

inxi -s

2015-03-28 linux , command

电子书

本站提供服务

最近文章

  • 从 Buffer 消费图学习 CCPM 项目管理方法 CCPM(Critical Chain Project Management)中文叫做关键链项目管理方法,是 Eliyahu M. Goldratt 在其著作 Critical Chain 中踢出来的项目管理方法,它侧重于项目执行所需要的资源,通过识别和管理项目关键链的方法来有效的监控项目工期,以及提高项目交付率。
  • AI Shell 让 AI 在命令行下提供 Shell 命令 AI Shell 是一款在命令行下的 AI 自动补全工具,当你想要实现一个功能,敲一大段命令又记不住的时候,使用自然语言让 AI 给你生成一个可执行的命令,然后确认之后执行。
  • 最棒的 Navidrome 音乐客户端 Sonixd(Feishin) Sonixd 是一款跨平台的音乐播放器,可以使用 [[Subsonic API]],兼容 Jellyfin,[[Navidrome]],Airsonic,Airsonic-Advanced,Gonic,Astiga 等等服务端。 Sonixd 是一款跨平台的音乐播放器,可以使用 [[Subsonic API]],兼容 Jellyfin,[[Navidrome]],Airsonic,Airsonic-Advanced,Gonic,Astiga 等等服务端。
  • 中心化加密货币交易所 Gate 注册以及认证 Gate.io 是一个中心化的加密货币交易所。Gate 中文通常被称为「芝麻开门」,Gate 创立于 2013 年,前身是比特儿,是一家致力于安全、稳定的数字货币交易所,支持超过 1600 种数字货币的交易,提供超过 2700 个交易对。
  • 不重启的情况下重新加载 rTorrent 配置文件 因为我在 Screen 下使用 rTorrent,最近经常调试修改 rtorrent.rc 配置文件,所以想要找一个方法可以在不重启 rTorrent 的情况重新加载配置文件,网上调查了一下之后发现原来挺简单的。