点阵字库 (Bitmap) 是最早被采用的一种数字化字库的格式,每个字形以黑白像素点阵矩阵组成。但是随着字号变大,数据量会呈几何级数增长,所以不适于复杂的大字号中文字形显示。但它在描述小字号时有明显的优势,可以加入人工的笔画取舍、合并和变形,使得字形尽可能地清楚展示。
随着显示设备分辨率和处理器性能的提高,点阵字已被曲线字所取代,或部分嵌入在曲线字中以提高小字的清晰度。它更多的应用是在低分辨率的设备上,例如老旧的手机、掌上电脑、仪器仪表、数码相机、收款机、银行或者邮局的票据打印机等。
PostScript 是美国 Adobe 公司发展的一种页面描述语言。所谓页面描述语言,实际上是一种专门的计算机语言用来描述和记录版面上的内容和结构。它以精确的坐标数据,精密的数学公式和规定的格式来定义页面上的各种元素,如文字、色彩、图形图像的位置、形状等等。
PostScript 字形描述技术是用美国 Adobe 公司的 PostScript 页面描述语言来描述字形的一种技术。 CID 字库是美国 Adobe 公司发表的最新字库格式,所有字形描述都采用 PostScript Type 1 格式,他具有易扩充、速度快、兼容性好、简便、灵活等特点,这种标准格式保证了跨平台的高质量输出。
CID (character identifier) 字符识别码,总字符集包括了一种特定语言中所有常用的字符,把这些字符排序,他们在总字符集中排列的次序号就是各个字符的 CID 标识码。CMap(character Map)字符映射文件,将字符的编码映射到字符的 CID 标识码,再用 CID 标识码从 CIDFont 文件中取到字形信息。 CIDFont 文件中不仅存储了字库中所有字符的描述,还包含了字体的提示(HINT)信息,它既能控制笔画的粗细,还能控制笔画之间空白,使解释器在字体比较小,设备分辨率低的情况下,得到细小清晰的笔画复杂的中日韩文字形。
常见的 ttf 文件,就是 TrueType 字库文件。
TrueType 是由美国苹果公司和微软公司联合提出的一种用数学函数描述电脑字体轮廓的技术。TrueType 采用几何学中二次 B 样条曲线及直线来描述字体的外形轮廓,含有字形构造、颜色填充、数学描述函数、流程条件控制、栅格处理控制、附加提示控制等指令。
TrueType 字体的主要特点在于它所见即所得。由于 TrueType 字体是由指令对字形进行描述,因此它与分辨率无关,均以设备的分辨率输出,既可以屏幕显示,又可以打印输出,无论放大缩小,字符总是光滑的,不会有锯齿出现。但是相对 PostScript 字体来说,特别是在文字太小时,其表现质量要差一些。
常见的 otf 字体文件,就是 OpenType Font 字库文件。
OpenType 字库是美国微软公司与 Adobe 公司联合开发的用来替换 TrueType 字型的数字化曲线轮廓字库格式。OpenType 字库采用 Unicode 编码,是 TrueType 格式的扩展延伸,扩展了 Adobe CID-Keyed font 技术。它在继承了 TrueType 格式的基础上增加了对 PostScript 字型数据的支持,所以 OpenType 字体中的字型轮廓数据既可以选择在‘glyf’表中 TrueType 格式轮廓,也可以选择在‘CFF’表中的 CFF(压缩字体格式,Compact Font Format)格式轮廓。
OpenType 字库信息小,字形可以所以缩放、变形(旋转、倾斜、弯曲)而不失真,具有很强的兼容性及独特丰富的排版特性。
经过几十年时间的演变,目前市场已经被 OTF, TTF 统治。基本上桌面平台,移动平台,大部分的系统都能兼容这两个字体。
之前的文章讲过 Vim Buffer 的管理 这使得工作可以在 Vim 中持续进行,而不需要退出然后重新载入文件。但是如果 Buffer 只能填满一个 Vim 窗口,假如想要在 Vim 中实现分屏,那么就必须要依赖于 Vim 的 Window。又因为 Vim 的 Windows 经常用来做分屏,又有的时候被称为 splits
。
Vim 在启动时只会打开单个窗口,可以使用 Ctrl-w s
来水平分隔窗口,或者使用 Ctrl-w v
来垂直分隔窗口。
在 Vim 中有很多方式打开 Windows
命令 | 解释 |
---|---|
<C-w>s |
水平切分窗口,新窗口显示当前缓冲区 |
<C-w>v |
垂直切分窗口,新窗口显示当前缓冲区 |
:sp[lit] { filename } |
水平切分窗口,并在新窗口载入{filename} 文件 |
:vsp[lit] { filename } |
垂直切分窗口,并在新窗口载入{filename} 文件 |
:new [filename] |
在当前 window 下方新建 window |
:vnew [filename] |
在当前 window 旁新建 window |
命令 | 解释 |
---|---|
<C-w>w |
窗口间循环切换 |
<C-w>h |
切换到左窗口 |
<C-w>j |
切换到下窗口 |
<C-w>k |
切换到上窗口 |
<C-w>l |
切换到右窗口 |
Ex 命令 | 普通模式命令 | 解释 |
---|---|---|
:clo[se] |
<C-w>c |
关闭活动窗口 |
:on[ly] |
<C-w>o |
只保留活动窗口,关闭其他所有窗口 |
总结一下常用的中文编码。
Unicode 是基于国际标准化组织(International Organization for Standardization,简称 ISO)所制定的 ISO/IEC 10646 ,即通用字符集(Universal Character Set,简称 UCS)的标准来发展,在 1991 年首次以书本的形式(The Unicode Standard)对外发布。
Unicode 的编码方式与 ISO 10646 的通用字符集(UCS)概念相对应,使用 16 位编码空间。16 位 Unicode 字符构成基本多文种平面(Basic Multilingual Plane,简称 BMP),最多可以表示 65536 个字符。基本满足各种语言的使用。最新的 Unicode 版本定义了 16 个辅助平面,两者合起来达到 32 位编码空间,可以涵盖一切语言所用的符号。目前辅助平面的工作主要集中在第二和第三平面的中日韩统一表意文字中。
Unicode 只与 ASCI I 兼容(更准确地说,是与 ISO-8859-1 兼容),与 GB 码不兼容。例如“汉”字的 Unicode 编 码是 6C49,而 GB 码是 BABA。
以上都是废话,下面重点:
理想是好的,一种编码解决所有问题。但是问题随即出现,对于英语这样的语言,1 个字节都不需要即可表达所有字符,而每个字符都需要 4 个字节的 Unicode 编码有些浪费空间。
尽管有 Unicode 字符非常多,但是实际上大多数人不会用到超过前 65535 个以外的字符。因此有了 UTF-16 (2 字节)编码,UTF-16 编码最明显的优点就是空间效率要比 Unicode 编码高两倍(除去 65535 意外的字符,每个字符只需要 2 个字节)
UTF-8 以字节为编码单元,没有字节序的问题。UTF-16 以两个字节为编码单元,在解释一个 UTF-16 文本前,首先要弄清楚每个编码单元的字节序。例如“奎”的 Unicode 编码是 U+594E, “乙”的 Unicode 编码是 U+4E59。如果我们收到 UTF-16 字节流“594E”,那么这是“奎” 还 是“乙”?
Unicode 规范中推荐的标记字节顺序的方法是 BOM。BOM 不是“Bill Of Material”的 BOM 表,而是 Byte Order Mark,他是一个特殊的非打印字符,可以把它包含在文档的开头用来指示所使用的字节顺序。对于 UTF-16 字节顺序的标记为 U+FEFE。
在 UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是 FEFF。而 FFFE 在 UCS 中是不存在的字符,所以不应该出现在实际传输中。UCS 规范建议我们在传输字节流 前,先传输字符”ZERO WIDTH NO-BREAK SPACE”。
这样如果接收者收到 FEFF,就表明这个字节流是 Big-Endian 的;如果收到 FFFE,就表明这 个字节流是 Little-Endian 的。因此字符”ZERO WIDTH NO-BREAK SPACE”又被称作 BOM。UTF-8 不需要 BOM 来表明字节顺序,但可以用 BOM 来表明编码方式。字符”ZERO WIDTH NO-BR EAK SPACE”的 UTF-8 编码是 EF BB BF。
UTF-16 不够完美,不是所有字符都能够使用 2 个字节长来表达,所以要在常数时间内定位到第 N 个字符,就不得不维护另外的索引,也就影响了编码本身的设计目的。所以就有了 UTF-8 编码,它是一种可变长度编码,可以用来表示 Unicode 标准中的任意字符。UTF-8 是一种前缀码,什么是前缀码:
因此,对 UTF-8 编码中的任意字节,根据第一位,可判断是否为 ASCII 字符;根据前二位,可判断该字节是否为一个字符编码的第一个字节;根据前四位(如果前两位均为 1),可确定该字节为字符编码的第一个字节,并且可判断对应的字符由几个字节表示;根据前五位(如果前四位为 1),可判断编码是否有错误或数据传输过程中是否有错误。
编码对应 Unicode 和 UTF-8 转换关系
位数 | 起 | 终 | 字节序列 | byte 1 | byte 2 | byte 3 | byte 4 | byte 5 | byte 6 |
---|---|---|---|---|---|---|---|---|---|
7 | U+0000 | U+007F | 1 | 0xxxxxxx | |||||
11 | U+0080 | U+07FF | 2 | 110xxxxx | 10xxxxxx | ||||
16 | U+0800 | U+FFFF | 3 | 1110xxxx | 10xxxxxx | 10xxxxxx | |||
21 | U+10000 | U+1FFFFF | 4 | 11110xxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | ||
26 | U+200000 | U+3FFFFFF | 5 | 111110xx | 10xxxxxx | 10xxxxxx | 10xxxxxx | 10xxxxxx | |
31 | U+4000000 | U+7FFFFFFF | 6 | 1111110x | 10xxxxxx | 10xxxxxx | 10xxxxxx | 10xxxxxx 10xxxxxx |
GB 2312-80 编码是中华人民共和国国家标准汉字信息交换用编码,全称《信息交换用汉字编码字符集基本集》标准号为 GB 2312-80(GB 是“国标”二字的汉语拼音缩写),由中华人民共和国国家标准总局发布,1981 年 5 与 1 号发布,1981 年 10 月 1 日实施。它是一个简化字汉字的编码,通行于中国大陆地区及海外使用简体中文的地区(如新加坡等)。
GB 2312-80 收录简化汉字及一般符号、序号、数字、拉丁字母、日文假名、希腊字母、俄文字母、汉语拼音符号、汉语注音字母、共 7445 个图形字符。其中汉字以外的图形字符 682 个,汉字 6763 个。
GB 2312-80 把收录的汉字分成两级。第一级汉字是常用汉字,计 3755 个,置于 16~55 区,按汉语拼音字母 / 笔形顺序排列;第二级汉字是次常用汉字,计 3008 个,置于 56~87 区,按部首 / 笔画顺序排列。字音以普通话审音委员会发表的《普通话异读词三次审音总表初稿》(1963 年出版)为准,字形以中华人民共和国文化部、中国文字改革委员会公布的《印刷通用汉字字形标》(1964 年出版)为准。
GBK 编码标准,全称《汉字内码扩展规范》(GBK),英文名称 Chinese Internal Code Specification,中华人民共和国全国信息技术标准化技术委员会 1995 年 12 月 1 日制定,国家技术监督局标准化司、电子工业部科技与质量监督司 1995 年 12 月 15 日联合以技监标函 [1995]229 号文件的形式,将它确定为技术规范指导性文件,发布和实施。这一版的 GBK 规范为 1.0 版。GB 即“国标”,K 是“扩展”的汉语拼音第一个字母。
GBK 向下与 GB 2312 编码兼容,向上支持 ISO 10646.1 国际标准,是前者向后者过度过程中的一个承上启下的标准。GBK 共收录 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。
GB2312 的 code page 是 CP20936,GBK 的 code page 是 CP936。GB18030 支持的字符数更多。GB2312、GBK、GB18030 均为双字节。从 ASCII、GB2312、GBK 到 GB18030 的编码方法是向下兼容的。
举一个最简单的例子,比如 祎
字,在 GB 2312 解码时可能就是乱码,而 CP936 并不会。
GB 18030 有两个版本:GB 18030-2000 和 GB 18030-2005. GB 18030-2000 是 GBK 的取代版本,它的主要特点是在 GBK 的基础上增加了 CJK 统一汉字扩充 A 的汉字,GB 18030-2005 的主要特点是在 GB 18030-2000 基础上增加了 CJK 统一汉字扩充 B 的汉字。
GB 18030-2000,全称《信息技术 信息交换用汉字编码字符集 基本集的扩充》,中华人民共和国信息产业部电子工业标准化研究所起草,由国家质量技术监督局于 2000 年 3 月 17 号发布。GB 18030-2000 共收录 27533 个汉字。
GB 18030,全称:国家标准 GB 18030-2005《信息技术 中文编码字符集》,是中华人民共和国现在最新的内码字符集,是 GB 18030-2000 的修订版。GB18030-2005 共收录汉字 70244 个。现行版本为国家质量监督检验总局和中国国家标准化管理委员会于 2005 年 11 月 8 日发布,2006 年 5 月 1 日实施。此规格为在中国境内所有软件产品支持的强制规格。
BIG-5 码是通行于台湾、香港地区的一个繁体字编码方案,俗称“大五码”。
BIG-5 码收录 13468 个符号和汉字,符号 408 个,汉字 13060 个,分为常用字和次常用字两部分,各部分中的汉字按照笔画 / 部首排列。其中:常用字 5401 个,次常用字 7659。
GB/T 12345-90 编码全称《信息交换用汉字编码字符集 辅助集》,标准号为 GB/T 12345-90,1990 年 6 月 13 日发布,1990 年 12 月 1 日实施,是一个关于繁体字的编码标准。所谓“辅助集”,是与“基本集”(GB2312-80)相对应而言。即:GB/T 12345 是与 GB2312 相对应的图形字符集。原则上,本字符集是将 GB2312 中的简化字用相应的繁体字替换而成。因此,这些替代的繁体字具有与被替代的简化字相同的编码;未曾简化的汉字以及非汉字图形字符,仍是 GB2312 中的汉字和图形字符,并具有与之相同的编码。 GB/T 12345-90 共收录 7583 个图形字符。汉字以外的图形字符 716 个,汉字 6866 个,其中一级汉字 3755 个,二级汉字 3008 个,增补汉字 103 个。 关于繁体字替换简化字的原则,GB/T 12345 注明:“本标准原则上按照《简化字总表》中所列繁体字与简化字的对应关系进行替换。”《简化字总表》由中国文字改革委员会 1964 年 5 月发表,后经国家语言文字工作委员会作个别修改,国务院 1986 年 6 月 4 号批准发表。
748 编码仅用于方正软件和系统,不做介绍
最近看笔记本,有一同学十分钟爱MSI的笔记本,于是乎就查阅了一下该笔记本的型号,顺手做一下笔记。以下就是MSI(微星)游戏笔记本常见型号,命名的解释。
##GE系列 入门级 体积与效能的平衡点 高端性价比
GE是主打影音系列,属于体积与效能的平衡点,体积并不会像GT或GX那样的庞大,不过仍有不错的效能。也可以说是入门级别的游戏本,主要是价格相对便宜。其中CPU可以自行更换,显卡为焊死在主板上的无法更换,单2.5寸硬盘位(SATA3接口)+单MSATA硬盘位(SATA3接口,主要用于MSATA接口的SSD升级)。相比GT和GX系列重量较轻,便携,因空间较小所以CPU和显卡及散热风扇为一体式设计,散热略差。 GE适合普通大学生用的,高端性价比选择,使用中端显卡,入门电竞规格,价格普遍便宜6000–9000左右。 GE可以上PCIE接口的SSD硬盘,不能再上另一块机械硬盘。但是GT本身是二个硬盘位,是可以上二块机械硬盘。GE散热是三根铜管,GT系列有五根散热导管。
##GS系列 超级本 GE基准的轻薄本 性能中高
GS 是以GE为基准再更加的轻薄,非常轻薄性能中高,配置和GE差不多,价格好像是13000左右,想要金属质感与薄型就买GS70。
##GT系列 发烧级游戏本 极致的规格、粗壮的体格加上高昂的价格
GT是主打游戏系列,纯种的高端发烧游戏本,档次从中到高都有,价格也相对贵些。简单来说就是极致的规格、粗壮的体格加上高昂的价格。其中CPU和显卡均可自行更换,升级性和扩张性好。 双2.5寸硬盘(SATA2+SATA3),支持RAID 0,同时支持微星独家的SUPER RAID技术,需通过微星独家的RAID卡实现,也因此牺牲了一个SATA3的硬盘位。相比GE系列重量较重,得益于大空间,散热为CPU独立散热+显卡独立散热+单风扇双风道设计,散热较好。特色功能有一键超频,另外丹纳音箱和赛睿的七彩背光键盘也很拉风。GT是一般都是目前顶级的显卡CPU,玩游戏最好,10000-30000W左右
##GX系列 中高级 AMD处理器 着重于GPU的效能
GX是主打单机游戏系列,奇葩的3A组合,显卡暴强而U爆弱,价格介于GE和GT之间。主要着重于GPU的效能(使用AMD的顶级显卡),CPU是使用中间的规格(像GX*40的Core i5,或是现在的AMD),所以价格又比GT系列来的更便宜。其中CPU和显卡均可自行更换,但是目前5750M已经是这台平台的最顶级U了,下代平台据说要更换新的接口了,7970M貌似可以升级8970M,有待验证。AMD的芯片组支持多SATA3,所以GX系列是双SATA3硬盘位+光驱位也是SATA3,同时也支持微星独家的SUPER RAID技术,需通过微星独家的RAID卡实现。GX系列外观和GT系列基本相同,内部构造则完全相同,得益于AMD平台的良好温控,散热是G系列里面最好的。GX是3A平台,虽然显卡是顶级的,但是CPU特差,玩一些网游和吃CPU的游戏直接跪,价格比GT便宜一些8000–10000。
##GP系列 以GE系列为基准将GPU降规来达到便宜的目的
GP最入门级的, GP系列以GE系列为基准将GPU降规来达到便宜的目的,纯粹是文书机,挂上G系列其实是来乱的。 如果你是土豪就用GT70 红龙吧,顶级CPU+780M顶规显卡,而且还可以上双显卡。优点是绝大部分游戏可Full HD特效全开且音质很棒,搭配多彩背光电竞键盘及杀手网卡与耳机强化输出。缺点是这机器至少3.5kg以上,此外变压器也很大颗,
这篇文章主要总结了我在使用 Vim 过程中遇到的一些问题及解决方案,都是一些比较零碎的内容,如果要看 Vim 系统的内容可以参考之前的几篇文章。
依赖 jq 命令:
sudo apt install jq
然后在 vim 中就可以:
:%!jq .
在 vim 中输入
:script
来查看 Vim 加载使用的配置
:version 来查看 Vim 的版本
在有一次使用 Vim 的时候总是无法将 Vim 选中的内容和系统粘贴板用到一起 "+y
和 "+p
根本无法使用,后来经过网上一查, 通过 :version
一查才知道原来本地安装的 Vim 版本根本没有把 clipboard 支持编译进去。所有有的时候遇到问题第一时间检查一下版本还是比较重要的。
使用 :map
来查看当前 Vim 配置中所有的快捷键映射。
如果使用 VS,或者 IDE 的同学应该都知道,如果要批量缩进代码,在这些 IDE 中都能够选择 +tab 键实现,而 Vim 中则不太一样,之前困扰我很久,现在终于有了解决方案。在之前的文章中已经提到了 Vim 的模式,现在我们要用到其中的一种 —- 选择模式。
批量缩进代码的方式如下:
>
缩进一次,按 <
回缩如果是需要选中的行数比较多可以使用 数字 num+j 方法移动 num 行,对于有括号 { } 的方法,例如
function functionName(){
// a lot of code
}
则可以使用 % 进行括号匹配,按下 v 进入选择模式,将光标移动到 { ,按下 % ,Vim 自动找到匹配的括号并选择该函数,利用 > 即可缩进该函数。
那么,其实单行缩进就是两个大于号 >>
, 回缩就是两个小于号 <<
。
在学习阶段,我经常改动 vimrc 文件,而每一次改动就要重启一下 Vim,甚是烦恼。偶然间看到 Google Group 中有人讨论一些无关紧要的问题,其中看到写了不重启使 vimrc 文件生效的代码,尝试一下确实可行,做一下记录:
在命令模式下运行
:so #MYVIMRC
去帮助查看 so,其实 so 是 source 的缩写
当然你也可以在 vimrc 文件中加入
"编辑 vimrc 之后,重新加载
autocmd! bufwritepost _vimrc source $VIM/_vimr
这样每一次保存 vimrc 文件就自动加载 vimrc 文件,使之生效。而如果在 vimrc 文件中存在函数,可能会遇到 vim 警告“函数 已存在,请加!强制替换”,同样讨厌,虽然作为新手的我还不知道为什么出现这些警告,但总之解决方法就是把 vimrc 中的函数全部定义成 function!
这种形式。但其实那些警告不影响效果,不定义成 function!
也行,但是很烦人。
均匀的在行与行之间插入空行,原先的空行保留。
Vim 的 :g
命令就是为类似的任务设计的,给每一行运行单独的命令。使用如下命令完成目标:
:g/.\n\n\@!/norm o
正则匹配 /.\n\n\@!/
,拆分成不同部分来解释:
.
匹配行中所有字符。(这个例子中用来排除空行)\n
匹配行末尾\n\@!
如果有连续两个换行则匹配失败用命令 :h E59
查看 \@!
更多信息。我们使用 :g
命令正则匹配到符合规则的行之后,我们告诉 Vim 执行 norm o
,也就是 Normal Mode 下的 o
命令,也就是在当前行下插入空行。
总结来说,这行命令匹配所有下一行不是空行的行,然后在他们下面增加一行空行。通过这个例子,你也许想要查看一下 vim 的 wiki Power of G 来学习一下 :g
命令,已经它的姐妹命令 :v
。
This note is taken from superuser
使用 shift+v 选中几行内容之后,如果只使用y 无法复制到系统的粘贴板中,此时在选中的情况下输入 "+y
, 即可将所选内容复制到粘贴板。注意需要输入的是:引号 + 加号 + 小写 y。
而这样做需要输入三次,可以使用 map 绑定到喜欢的快捷键上,比如:
vmap <C-c> "+y
这一行配置的含义就是在可视模式下,Ctrl+c,就是将所选择内容复制到粘贴板。 但是需要注意的是如果运行 :echo has('clipboard')
返回的结果是 0,那么这个方法就没用,因为该版本的 vim 在编译的时候没有将 +clipboard 加入。
同理,如果想要从系统粘贴板中粘贴内容到 vim 中,使用 "+y
or "*y
, 引号 + 加号 +y,来从系统粘贴板中将内容粘贴到 vim 中。
Vim 中极好用的文件管理插件,用了也有一些时间了,但是有些内容并没有仔细地看,今天突然有些需求就看了一下。常用的 NERDTree 命令有:
打开 NERDTree,在 NERDTree 中使用m
然后选择a
,来创建文件或者文件夹,要创建文件夹只需要在输入的名字后面加上/
。
同理,在 NERDTree 中按下 m 会由很多选项可选,使用 d 就可以删除结点,也就是删除文件或者文件夹。
在 NERDTree 中使用Shift+i 来显示隐藏文件。
使用命令:
:g/^/+d
:g
命令在所有匹配正则的行上执行
:g/LinesMatchThisRegex/ExecuteThisCommand
举例:
:g/hello/d
以上命令会删除所有包含 “hello” 的行
而与此同时 :%s
仅仅提供正则的搜索和替换,命令最后的 g 表示全局,整个文件中
:%s/hello/world/g
因此该命令会替换文中所有的 hello 为 world.
:%s
中的 s 表示替换 (substitute) , 而 % 表示整个 buffer. 因此 :%s
表示从整个文件 buffer 中替换,:%s
还可以指定行范围:
:10,15s/hello/world/g
搜索并替换 10 至 15 行中的 hello 为 world.
在 vim 中移动 hjkl, 左下上右移动光标已经不用多说, wb, 向后向前移动一个 word。
gg 移动到第一行, G 移动到最后一行,这是最基本的,也可以使用 nG 来移动到第 n 行。
翻页技能,使用 Ctrl D 向下移动半页, Ctrl U 向上移动半页
Ctrl B 向上翻页, Ctrl F 向下翻页
*
号用来向下查找整个单词#
号用来将光标移动到上一个在光标下的字符,比如光标正在单词 String 上,使用 #
来向上查找上一个 String。%
百分号用来在匹配的括号之间跳转。fx
光标跳转到下一个 x 位置,可以用来快速跳转到下一个预期的字符 xFx
向前跳跃到字符 x 位置tx
til 下一个 x,光标在 x 前面Tx
上一个 xsudo apt install vim-gnome
配置的 leader 要在 map 之前
let mapleader = ","
let g:mapleader = ","
使用现在的配置有一段时间了,不过最近有一篇文章,因为没有使用 Vim 的保存,而丢失了部分,所以想到了 Vim 应该能够自动保存的。在我丢失部分为保存内容的时候,我想起了 Vim 的 swp 文件,可惜的是我在 vimrc 配置中禁用了 swp 文件
set noswapfile
所以丢失了 swp 文件的我,依然找不回来丢失的内容。网上大致搜了一下,真的有解决方法,在 vim 丢失 focus 的时候自动保存 1
:au FocusLost * :wa
:au FocusLost * silent! wa
把这句话放到 vimrc 中,保存。另外一种方法就是 autocmd CursorHold * update
,CursorHold
命令会在用户间隔 updatetime
时间 (milliseconds) 没有按下任何按键时被触发。:update
命令会保存被修改的 buffer。如果想要在插入模式下面也自动保存,那么 CursorHoldI
事件也可以被使用:
autocmd CursorHold,CursorHoldI * update
将光标停在数字上,Vim 中 Ctrl + x 会将数字减 1, 而 Ctrl + a</kdb> 能将数字加 1 , 默认为 8 进制。
前段时间听到一个问题:“Vim 如何在插入模式下移动?“,一开始听到这个问题的时候,我有点楞,但是对于这个问题,我开始相信有解法的,毕竟 Vim remap 还是很强大的,大致搜了一下,大部分的答案是使用 imap <C-n> <Down>
这样将 Ctrl + n 来映射到向下移动,但直到我看到了这样一则评论:
Vim is designed for navigation to be done in normal mode and text insertion to be done in insert mode. You will be much happier and more productive in the long term if you learn to use Vim the way it was designed to be used instead of fighting it. If you try it for a while and find you really don’t like a moded editor, you may want to try Emacs. It is another very powerful editor, but lets you navigate and edit without changing modes. – garyjohn Jan 7 ‘13 at 7:05
顿时我恍然大悟,Vim 设计的一大准则就是将文本的移动放到了 normal mode 中,只有插入文本的时候才会进入 insert mode。而对于这个问题,其实本质上是对 Vim 设计的挑战。所以才有了 Emacs,可以在不切换模式的情况下在编辑器中快速移动。我平时在使用的时候,其实这个需求也很少,并且 ESC ,从插入模式到 Normal mode 也不是很难的操作,所以对于我来说还好,不过可能对于许多刚刚接触 Vim ,并且对以前无模式编辑器使用比较深入的人来说,可能是一个比较难越过的坎。
不过 Vim 在 Insert mode 下还是有两个比较常用的快捷键
在 Vim 命令行下, Ctrl-r Ctrl-w
会复制光标下的单词并插入到命令行中。
:!mkdir -p %:h
:write
:w !sudo tee % > /dev/null
http://vim.wikia.com/wiki/Auto_save_files_when_focus_is_lost ↩
Vim 学习笔记进阶版,初级版可以参考这篇文章
这篇文章主要分为替换操作,多窗口操作,Vim 的 Tab 操作,以及 Visual mode 命令模式等等。
Vim 所有的操作都是原子化的,将操作组合起来能够实现非常快捷的 Input。在引入 .
命令时需要记住这么几条原则, Vim 哲学的第一条,不要重复自己,所有重复的命令都可以使用 .
来实现,而在这一条之后需要注意的是使得操作可重复,每一次的编辑命令有意识的让其可以重复,这样就可以达成一键移动,一键执行,来实现重复编辑的脏活累活。
. (dot) will repeat the last command 点命令重复上一个命令
n<commmand> will repeat the command n times 将命令重复 n 次
for example:
2dd will delete 2 lines
3p will paste the text 3 times
40idesu [ESC] will write "desu " 40 times
5w 向后移动 5 个单词
6j 向下移动 6 行
Vim 还支持另一种组合
di" 光标在引号内, (d)elete (i)nside " 删除在引号之间的内容
yi( 光标在括号内, (y)ank (i)nside () 复制在 () 中的内容
vi] 光标在中括号内, 选中 [] 内的内容
dtx 向后删除字符直到遇到第一个 `x` 字符, (d)elete (t)ill x
ytx 向后复制内容直到遇到第一个 `x` 字符
以下是命令 c 加上一些操作,其他 d(elete) y(ank) v(iual) 都可以接
ctx 向后修改内容到 `x`,也就是意味着删除光标到 `x` 中间内容,并进入插入模式
ci" 改写双引号中的内容
ci' 改写单引号中的内容
cib 改写小括号中的内容
cab 改写小括号中的内容(包含小括号本身)
ci) 改写小括号中的内容
ci] 改写中括号中内容
ciB 改写大括号中内容
caB 改写大括号中的内容(包含大括号本身)
ci} 改写大括号中内容
cit 改写 xml tag 中的内容
cis 改写当前句子
c2w 改写下两个单词
ct( 改写到小括号前
nG go to line N, N is a number, like 23G means go to line 23
:x 跳转到第 x 行 x 为行号
gg shortcut for 1G - 跳转到第一行
G 跳转到最后一行
ma 将当前位置标记为 a,26 个字母都可以作为标记,`mb`, `mc` 等
'a 跳转到 a 标记位置
qa 将所有的键盘操作录制下来,直到再次在命令模式按下 <kbd>q</kbd>, 并存储在 <kbd>a</kbd> 中
@a 执行刚刚记录在 <kbd>a</kbd> 中的键盘操作
@@ 执行上一次 macro 操作
宏命令是 Vim 中最神奇的操作之一,需要慢慢体会,关于宏命令可以参考这篇
简单的大小写替换可以使用:
~ 替换大小写
g~iw 替换当前单词大小写
gUiw 将单词转为大写
guiw 将单词转为小写
gUU 全行转为大写
guu 全行转为小写
在全文中用一个单词替换另外一个单词
:%s/ 想要被替换的字串 / 新字串 /g
:1,$s/
,如果不加 %
则表示在当前行中替换的语法为::[addr]s/ 源字符 / 目的字符 /[option]
[addr] 表示检索范围,省略表示当前行。
s: 表示替换操作
[option] 表示操作类型
省略 option 时只对每一行的第一个匹配串进行替换
删除所有空行
:g/^$/d
删除所有空白行和空行
:g/^[ ][ ]*$/d
在每行开始插入两个空白
:%s/^/ /
在接下来 5 行末尾加入"
:.,5/$/"/
在 Normal 模式下使用以下命令新建窗口
:split 水平分割窗口,内容一样
:sp split 缩写
:10split 水平分割窗口,新窗口高度 10 行
:split filename 窗口中打开新文件
:new 功能和 split 一样
:vsplit 垂直分割窗口,简写 :vs
:vsp 垂直分割
Ctrl-w s,v 分割窗口的快捷方式,s 水平分割,v 垂直分割
:clo[se] 关闭窗口
Ctrl-w c 关闭当前窗口
:on[ly] 只保留激活的窗口,关闭其他窗口
Ctrl-w w w 窗口间循环移动 Ctrl-w Ctrl-w 同样
Ctrl-w h,j,k,l Ctrl 按下,按下 w 松开,Ctrl 松开,按 hjkl 对应左下上右
Ctrl-w H,J,K,L 大写 HJKL, 移动窗口
Ctrl-w o 让当前文件占据整个窗口,同时会关闭其他窗口
`Ctrl-w < >` 调整窗口宽度,`<` 缩小当前窗口宽度,向左扩展一列,`>` 增加当前窗口宽度,向右扩展一列。当然 `Ctrl-w` 之后可以使用 `n+<` 调整多列宽度
`Ctrl-w - +` 调整窗口高度
`Ctrl-w_` 高度最大化
`Ctrl-w|` 宽度最大化
在使用 Nerd tree 插件后,可以使用 Nerd tree 内置的快捷键,在 Nerd tree 中
i
split 一个新窗口打开选中的文件,并跳转到该窗口s
vsplit 一个新窗口打开选中文件,并跳到该窗口在 Vim 中 Tab 和 Windows 是不一样的概念,如果平时使用 Chrome 或者 Firefox,就很好理解 Tab,中文可以翻译为标签页,但是 Vim 中 Tab 和正在编辑的 buffer 不是一对一的关系,在 Vim 中每一个 Tab 能够包含多个窗口 Window。
有很多方法可以创建新 Tab , 这里是最简单方式:
:tabnew create a empty new tab
:tabedit {file} edit specified file in new tab
Some ways to close tabs:
:tabc[lose] close current tab
:tabclose {i} close i-th tab
:tabo[nly] 只保留当前 tab,close all other tabs
Some ways to move tabs:
:tabm 0 move current tab to first
:tabm move current tab to last
:tabm {i} move current tab to position i+1
:tabs list all tabs including their opening windows
Ways to move between tabs:
:tabn[ext] go to next tab
:tabp[revious] go to previous tab
:tabfirst go to first tab
:tablast go to last tab
While in normal mode, you can type:
gt go to next tab
gT go to previous tab
{i}gt go to tab in position i
Insert 模式下
<BS> 退格键,删除光标前
<Del> Delete 键,删除光标后
<C-W> 删除一个单词
<C-U> 删除光标前的字符,保留光标之后的文本,保留行首的缩进,只删除第一个非空字符至光标位置之间的文本。
v 按字符选择,在 Normal mode 下按下 v 进入 Visual mode
V 按行选择
Ctrl+Q 块选择,Windows 下,其他平台下 Ctrl+V
选择字符之后操作
d 剪切选择内容到剪贴板
y 拷贝选择内容到剪贴板
c 剪贴选择内容到剪贴板并进入 Insert mode
:! command 暂时离开 vi 到命令模式下执行 command
在命令模式下,可以不离开 Vim 进行操作,但如果想要把命令的结果粘贴到 Vim 中,就需要使用 read 命令
:read !ls -al
Vim 会在当前光标处插入命令执行的结果。
:verbose set tabstop? in Vim, it will tell you where the tapstop option value is coming from
:help + command 查看 Vim 命令的帮助,比如想要查看 c 命令的帮助直接使用 `:h c` 就能查到。
g <C-g> 单词统计
差不多看到这里就能够直接看文档了:http://vimcdoc.sourceforge.net/ 通过文档学习更多符合自己使用习惯的命令或者操作。
还有一些参考资料
Vim 入门及简单使用,包括简单介绍 Vim 模式,移动,和编辑命令。
这篇文档相较于之前的入门教程会相对比较丰富,建议入门后再阅读。可以了解到在基础操作上一些能够快速提高效率的方法。
如果你不知道 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
在不移动光标的情况下,将文档向上或者向下移动一行。
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 列
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
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 的快捷键一致
u 撤销上一次编辑 undo
Ctrl-r redo
/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 替换
: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! 为放弃为保存的修改
gg 移动光标到文件开头
G 移动光标到文件末尾
Ctrl-O 跳转到上一个位置
Ctrl-T 标签退栈
g; / g, 上一个 / 下一个修改点
之前的一篇文章介绍了 Vim 的多模式,这篇文章重点来讲一讲如何在这些模式之间随心的切换。
在普通模式和可视模式之间切换。
上一篇文章 提到过 v
是通向可视模式的大门,记住 v
普通模式切换到可视模式可以有如下的方式:
命令 | 作用 |
---|---|
v |
字符可视模式 |
V |
行可视模式 |
Ctrl-v |
块可视模式 |
gv |
重选上一次高亮区域 |
如何从可视模式回到普通模式
命令 | 作用 |
---|---|
Esc | 最常用的回到普通模式 |
Ctrl-[ | 回到普通模式 |
v / V / Ctrl-v | 在对应的模式下回到普通模式 |
如果想要在可视模式不同状态间调整,比如想要将字可视模式切换成行可视模式,那么直接按下对应的 V
即可。
高亮选区的范围由两个端点决定,可以使用 o
来切换活动端点。比如说有种情况,选择选区时,发现选区开始位置不对,这时不用退出可视模式,从头开始,只需要按 o
,将活动端点切换为开始端点,重新调整选区即可。
这个时候有人就要问了,对于字可视模式和行可视模式比较好理解,只有两个端点,可视如果是快可视模式,那么对于框有四个点,这个时候就需要依靠 O
来切换,在块可视模式中 O
会移动到同一行的另一端。而其他情况 O
和 o
一样。
可视模式和插入模式之间切换,绝大多数情况都是从 Visual 模式切换到 Insert 模式,做一些任务之后在回去。似乎很少遇到直接从 Insert 模式中切到 Visual 模式的,所以这里就直接介绍一下从 Visual 模式切换到 Insert 模式。
和普通模式切换到 Insert 模式类似,在可视模式下也可以直接使用如下按键:
命令 | 作用 |
---|---|
c | 删除选区内容并进入插入模式 |
I / A | 在行可视,块可视模式下跳转到行首行尾 |
在任何模式下输入 :
就会进入 Ex 命令模式。
单元测试是白盒测试,又被称为模块测试,是最小的测试单元。
单测应该做到:
为什么需要单测
测试的内容可以包括
评价测试的指标,覆盖范围,是否测试代码覆盖了基本表达语句,基本逻辑块。
Mock 使用场景
Mock 工具工作的过程
目前比较流行的 Mock 工具有 EasyMock,jMock,Mockito,Unitils,Mock,PowerMock,JMockit 等等
Unit test 执行前后不能对环境造成污染,避免写有副作用的 TestCase
自我清理:
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
保持效率
测试粒度
结果验证
保持独立
仅测试公有接口
覆盖边界值
– 确保参数边界值均被覆盖。对于数字,测试负数、 0 、正数、最小值、最大值、 NaN (非数字)、无穷大等 – 对于字符串,测试空字符串、单字符、非 ASCII 字符串、多字节字符串等 – 对于集合类型,测试空、 1 、第一个、最后一个等 – 对于日期,测试 1 月 1 号、 2 月 29 号、 12 月 31 号等
编写反向测试
单元测试无法证明代码正确性,一个失败的单测表明代码可能有错误,但一个成功的单测什么也不能证明。
经Code Rush推荐,之后又陆陆续续看到很多在使用这款插件,所以在入门插件的时候就第一个安装了此插件,VIM如果不依靠插件来增强功能可谓鸡肋。而VIM提供的插件又很多,新手可能无从下手。幸好让我接触到了这个Vundle插件,Vundle用来安装,管理其他插件,这样以后安装插件卸载插件的问题就迎刃而解了。用Vundle管理插件有以下好处:
安装git客户端 Mac和Linux一般默认已经安装
下载并安装Vundle
git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim
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
安装插件
启动vim,并运行:PluginInstall
查看官方教程,官方的教程有点问题,完全按照所写配置并不能成功。
vim74 #主程序目录 对应变量 $VIMRUNTIME
vimfiles #配置文件目录 对应变量 $VIM
同样需要Git,并且需要Curl
下载安装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
设置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
因为Windows下和mac,linux环境不同,vim的配置地址也不同,所以git clone到的目录如下:
git clone https://github.com/gmarik/Vundle.vim.git vimfiles/bundle/Vundle.vim
_vimrc
需要将Mac和Linux中相应位置代码修改成如下代码:
" 配置同Mac,只需要按照下面修改rtp的路径即可
set rtp+=$VIM/vimfiles/bundle/Vundle.vim/
let path='$VIM/vimfiles/bundle'
call vundle#rc(path)
使用方法很简单,只需3步使新插件生效即可
常用命令
:PluginList - 枚举已安装的插件列表
:PluginInstall - 安装插件或者后面加上'!'更新
:PluginUpdate - 更新插件 同 :PluginInstall!
:PluginSearch foo - 查找插件。例如查找名称为foo的插件。或者后面加'!'更新本地缓存
:PluginClean - 清理无用插件或者后面加'!'自动清理
更多使用方法查看帮助 :h vundle
参考: