3.1 配置文件.vimrc_vimrc

.vimrc文件是个人定制Vim的脚本文件,该文件中的每一行都会被当作Ex命令在Vim进行初始化的时候执行。一般在类Unix系统中把该文件存放在$HOME/.vimrc或$HOME/.vim/vimrc,windows下存放在$HOME/_vimrc, $HOME/vimfiles/vimrc 或 $VIM/_vimrc中,MacOS系统放在$HOME/.vimrc, $HOME/vimfiles/vimrc 或 $VIM/.vimrc (或 _vimrc)。

.vimrc文件并不是Vim安装的,如果要定制自己的Vim,首先要在上述的目录创建该文件。创建后在该文件中添加自己的设置,在buffer中显示行号,可以添加如下一行:

set number

一般每行一条命令,如果想在单行添加多条命令需要用’|’字符进行分隔。

3.2 $HOME/.vim目录及其子目录

除了可以在vimrc文件中定制Vim,用户也可以根据自己的需要安装第三方插件。比如通过第三方的mru.vim插件实现最近打开列表功能,这个插件要放在目录$HOME/.vim/plugin下,每次运行Vim时输入:MRU命令可以查看最近打开文件列表。再比如当进行文件类型检测的时候,要设置缩进格式、每行字符数、是否需要空格替换制表符、是否需要自动缩进等,可以自己实现一个特定文件类型的定制插件,放在$HOME/.vim/ftplugin目录下,这样Vim就可以随时根据用户需要对文件格式进行设置了。另外在Vim运行的生命周期中,可能打开了c文件,同时还打开了pyhon文件,这里一个文件类型是c,另一个是py,它们需要不同的格式设置,自己可以分别完成一个c.vim和一个py.vim插件放在$HOME/.vim/ftplugin目录下,用户不再需要关心格式相关的问题,你只要打开对应类型的文件,Vim都能按照你的意愿自动帮你完成设置。$HOME/.vim目录是用于存放第三方插件的根目录,可以在该目录下创建一些规定的子目录用于特定目的,下面对这些常用的子目录进行简单说明。

  1. plugin和doc

用于存放第三方插件和它们的帮助文档,可以在网上搜索到很多第三方插件,它们很多是压缩包,解压后包含plugin和doc两个目录,需要把plugin目录下以.vim为后缀的Vim脚本放入$HOME/.vim/plugin目录,doc目录下的txt放在$HOME/.vim/doc目录下。Vim再次初始化时会默认加载$HOME/.vim/plugin目录下的所有插件。如果不想退出Vim,可以执行”:source $HOME/.vim/plugin/xxx.vim”命令加载新的插件。

2. ftplugin

该目录用于放置文件类型相关的插件。在设置”filetype plugin on”的情况下,Vim会在打开某种类型的文件时对文件类型进行检测,然后加载该目录下对应的插件,执行属于自己的设置。在本节开始已经提到,可以定制任何你需要的参数。这里需要注意的是Vim在加载该目录下的插件时对文件名称有要求,比如要定制自己的c语言文件的格式,需要命名为c.vim或c_xxx.vim(xxx代表任意可以作为文件名的字符串),任何其他名称不会被Vim识别。

3. ftdetect

如果你不想用Vim默认的文件类型检测功能或者Vim不包含你的文件类型的相关设置,那么Vim允许用户实现自己需要的文件类型检测插件,可以把它们放在$HOME/.vim/ftdetect目录下。例如实现对mine类型的检查,写一条自动命令(3.15节自动命令)进行动态文件类型检测:

au BufRead,BufNewFile *.mine set filetype=mine

然后保存该文件

:w $HOME/.vim/ftdetect/mine.vim

这样Vim就可以识别mine类型的文件了。

4. autoload

随着对Vim的深度定制,Vim初始化时所加载的插件越来越多,其中可能包含一些大型插件,导致Vim初始化非常耗时。autoload的目的就是尽量延迟插件的加载。

引用autoload目录下的插件时,需要提供文件路径、文件名和函数名,并用’#’连接它们。例如,autoload目录下有一个插件名为bar.vim,bar.vim中定义了函数test(),要通过如下方式调用test函数:

:call bar#test()

如果,bar.vim插件存放在autoload子目录foo下,也就是autoload/foo/bar.vim,为了调用test()函数,需要如下使用如下格式:

:call foo#bar#test()

引用autoload目录下插件中的全局变量使用同样的方式。

5. after

该目录主要用于存放只对Vim内置插件功能进行小小的增强或改动的插件。比如说在你想要设置c语言文件的textwidth宽度为80,新建一个c.vim脚本,输入”setlocal textwidth=80”,然后放在$HOME/.vim/after/ftplugin目录中。Vim再次启动时会根据文件类型加载该目录中对应的插件,类似于$HOME/.vim/ftplugin目录。

3.3 .swp文件

以.swp为后缀的文件用于存储对文件的修改,它的命名方式是在当前打开文件的名字前加一个’.’(成为隐藏文件),然后加一个后缀“.swp”。例如,Vim正在打开一个名为aaa.c的文件,那么对应的swp文件名为.aaa.c.swp,当关闭aaa.c文件后,swp文件会立即被删除。需要注意的是,在vim非正常退出后,swp文件可能仍然存在,再次打开swp文件对应的文件时vim会询问用户需要的操作,如图3.1:

5个选项分别为只读打开、编辑、恢复、退出、终止等,用户根据需要做出选择。如果你认为不需要恢复则可以直接删掉这个swp文件,再打开文件。

3.4 viminfo

1. viminfo文件是Vim用来记录退出时的状态,当再次运行vim时可以快速恢复这些状态,该文件会存储以下信息:

  • 命令历史
  • 搜索历史
  • 输入行历史
  • 非空寄存器的值
  • 多个文件的书签
  • 纪录浏览文件时所停留过的位置
  • 最后一次搜索/替换的样式
  • buffer列表
  • 全局变量

2. Vim提供’viminfo’选项用来定制在viminfo文件中要存储哪些信息以及存储数量。表3.1中列出了该选项中常用标志:

‘viminfo’在8.0.1453版本的默认值是“‘100,<50,s10,h”,根据上面的表格可以知道”’100”表示最多纪录100个文件的浏览标记,”<50”表示每个寄存器最多保存50行数据,”s10”表示最多保存每个寄存器中10kb的数据,”h”表示取消高亮搜索结果。

3. 如何在下次运行Vim时打开最后一次浏览的文件并定位到插入符最后的位置呢?

在viminfo纪录的文件的数据中,书签’0-‘9纪录了插入符所停留过的位置,其中’0保存当前的位置,’1保存上一个’0值,’2保存上一个’1值,以此类推。所以’0保存了退出Vim时的文件名和文件内位置,运行下面命令可以直接打开上次退出时的文件及对应的位置。

vim -c "normal '0"

3.5 状态栏

状态栏在Vim底部命令行区域之上,它可以显示和当前打开文件有关的信息,通过’statusline’选项可以定制用户需要显示的内容:

更多选项请查看:h ‘statusline’选项的帮助。

‘laststatus'选项用于控制状态栏的显示行为:

  • 0 - 不显示状态栏
  • 1 - 多于一个窗口的时候显示状态栏
  • 2 - 总是显示状态栏

在选择每个选项时,要在前面加上’%’,请看下面的例子:

:set statusline=[%f]%r%w%m%=%l/%L,%c %p%%

:set laststatus=2

每个选项的含义请参考上表3.2。

为statusline定制颜色:

  • 井号’#’ - 使用highlight默认定义的颜色方案。执行:hi[ghlight]命令查看当前可用的高亮颜色组合.
  • 星号’*’ - 使用用户定义的颜色方案,Vim为用户提供最多9个自定义颜色组合。

例子,(a)在状态栏中显示文件相对路径,颜色显示为白底绿色;(b)用highlight预定义的颜色组合LineNr修饰行号:

hi User1 ctermbg=White ctermfg=Green
set statusline+=%1*%f%*
set statusline+=%#LineNr#
set statusline+=%l

3.6 缓冲区(buffer),窗口(window)和标签页(tab)

  1. buffer

buffer是Vim和实际文件交互的通道,它存在于内存中。Vim打开文件时在内存中建立对应的buffer,在Vim进行文件编辑时实际是对buffer的编辑,只有执行写入命令的时候才对文件进行实质性的操作。

只运行Vim时,Vim会创建一个空的buffer,它不和任何文件关联。

buffer列表的查看命令是”:ls”,”:buffers”或”:files”,可以用”:{buffer number}buffer”的命令进行遍历,也可以通过命令“:bnext/:bprevious”等命令进行遍历。更多帮助信息请查看帮助文档:h windows.txt第十一节Using hidden buffers。

2. window

上面的buffer创建好了需要通过Window来显示,window提供buffer的可见视图,一个buffer可以对应一个或多个window。

可以用“:split”或“:vsplit”命令分别创建一个水平分割或垂直分割的窗口。或者在Vim初始化时传入”-o”或”-O”参数后跟多个文件,Vim为每个文件创建一个window。例如,打开三个文件每个文件对应一个window,窗口之间水平分割:

vim -o file1 file2 file3

更多详细信息请查看:h windows.txt。

3. tab

tab是窗口的集合,所以它可以包含一个或多个窗口。创建tab的命令是”:tabnew”。也可以在Vim初始化时传入-p参数后跟多个文件,此时每个文件对应一个tab。例如打开三个文件,每个文件对应一个tab:

vim -p file1 file2 file3

可以用”:tabnext/:tabprevious”命令对tabs进行遍历。更多详细信息请查看:h tabpage.txt。

3.7 寄存器

Vim的寄存器用来保存编辑内容或者其他一些Vim状态的一组容器或者变量,它们大致分为两类,一类是自动更新的,例如执行"d" "c" "x" "s" "y"等操作符时,无名寄存器""自动保存删除的内容,".寄存器自动保存添加的内容;另一类需要手动保存内容,例如"a-"z寄存器。下面是来自Vim帮助文档change.txt中对所有寄存器种类的描述:

  1. 无名寄存器""

Vim用删除命令d, c, x, s和复制命令y来填充这个寄存器,

2. 10个数字寄存器"0到"9

数字寄存器保存yank和delete命令操作的内容。”0寄存器保存最后一次执行yank的相关的内容,只有这一个数字寄存器受yank命令影响,其他的都是delete命令使用。”1寄存器保存最后一次删除的内容, “2到“9寄存器会顺移“1中的内容,也就是如果多次执行删除命令,“1中的内容移动到”2,“2中的内容移动到”3,以此类推,“9中的内容最终会被丢弃。

3. 低级的删除寄存器"-

当只删除某一行的部分内容时,被删除内容保存在这个寄存器中。它与”0寄存器不是冲突的。

4. 26个命名寄存器"a到"z或者"A到"Z

这组寄存器供用户使用,选择"a-"z保存目的文本,"A-"Z用于追加内容到"a-"z寄存器的末尾。例如,复制某一行内容到"a寄存器中:

“ayy

通过:reg "a命令查看当前"a的内容,然后追加另外一行到"a寄存器中:

“Ayy

再通过:reg "a命令查看当前"a的内容,这时"a内容是被追加过的。粘贴"a中的内容时用寄存器后跟p命令:

“ap

5. 3个只读寄存器

".寄存器保存最后插入的内容。

"%保存当前窗口所显示文件的路径。

":保存最后一条被执行的命令。

6. 交换buffer寄存器"#

保存当前窗口上一次打开文件的路径。

7. 表达式寄存器"=

执行一个表达式,而不是保存文本。

8. 选择寄存器"*, "+

“*和”+用于和系统剪切板进行交互,复制内容时可以使用下面命令:

“+y或”*y

9. 黑洞寄存器”_

丢弃内容的时候使用,类似于Linux中的/dev/null文件。如果在执行命令时不想影响其他寄存器,可以显示指定该寄存器。例如删除一行:

”_dd

注意是个这个寄存器删除的内容无法找回。

10. 搜索样式寄存器"/

保存用/或?命令上一次搜索的内容。

3.8 "."命令

“.”命令用于重复最后一次改变的内容,可以通过数量控制单次执行该命令的次数,命令原型为”{count}.”。下面是向下逐行删除的例子:

dd
j
.

3.9 宏

其实在Vim并没用宏这个概念,在帮助文档中用的标题是"Complex repeats",即复杂的重复,但是本质上和宏没有区别,所有我们在这用“宏”这个名词代替。

宏可以记录一组命令,用来重复复杂的操作。宏可以记录插入符的移动和文本编辑等操作。

在录制宏的过程中,可以把记录的操作步骤存入{0-9a-zA-Z}(大写字母的寄存器用来添加内容)寄存器中,具体操作步骤如下:

  1. 在正常模式下,先按q键后跟寄存器名。比如要录制一个名为a的宏,就要按下qa,这时在Vim的命令行出现"recording @a"字样。
  2. 开始输入命令进行操作。
  3. 完成操作后,按q键结束宏的录制。
  4. 按@a键执行上面录制的宏,可以加入次数控制,例如执行3次宏a,则按3@a。
  5. @@命令执行上次执行的宏,也可以可以加入次数。
  6. :reg registers查看宏的命令序列。

3.10 操作符和动作命令

操作符是为了修改文本而存在的一种命令,它们大致有下面几种模式:

  • {count}operator-operator,重复操作符首字母执行某些特定的操作,例如"dd"删除当前行,”yy”复制当前行。还可以在前面加操作的数量,例如"5dd"删除从插入符所在行开始向后的5行。
  • {count}operator,单个操作符在正常模式下执行,例如"~"执行当前插入符下字符的大小写反转,也可以指定字符的数量操作多个字符。
  • {count}operator{count}{motion},操作符加一个动作{motion}(3.10.2节 动作),必要时指定一个数量值,比如删除5个单词d5w。动作{motion}指定了操作符的操作范围。
  • g-char,小写字母g后紧跟一个字符实现某些固定的操作,例如大小写反转g~,文本格式化gq等。

1. 通常的操作符有:

a. 删除操作符d(delete)

该操作符是删除所选的内容,被删除的内容保存在无名寄存器“”(:h “”)和数字寄存器”1中,可以通过paste命令粘贴该寄存器中的内容。

b. 复制操作符y(yank)

类似于windows中的复制操作,同样所复制的内容保存在无名寄存器“”和数字寄存器“0中。

c. 粘贴操作符p(paste)

粘贴无名寄存器(“”)中的内容。小写p粘贴到当前行的下面位置,大写P粘贴到当前行的上面位置。

d. 操作符c(change)

删除选择内容的同时进入插入模式。例如删除文本并进入插入模式的几种操作cw(W)或c$:

cw或cW删除一个单词并进入插入模式,其中w遇到非字母字符会停止,W遇到空白字符才停止。

c$删除插入符所在位置到行尾的字符并进入插入模式。

e. 操作符g

g操作符没有固定种类的操作,常用的操作有如下几种:

  • g~ 反转大小写
  • gu{motion} 当前文本中的字符转换为小写
  • gU{motion} 当前文本中的字符转换为大写

需要注意的是,这里所说的g操作符都是关于内容编辑的命令。

f. 操作符z

和g操作符一样,也是一个难以归类的操作符。它包含多种操作,例如重画窗口、文本折叠、拼写检查相关的操作等。例子,对一个c函数创建一个折叠区域,然后执行折叠命令,再打开该折叠,最后删除该折叠区域:

g. 其他操作符

  • = c代码缩进
  • > 文本向右移动
  • < 文本向左移动

2. 动作命令(motion)

动作命令用于辅助操作符执行操作,Vim定义了几种移动插入符的方式,完成移动后产生不同的文本范围(插入符移动前到移动后的位置)提供给操作符。Vim的动作命令大致有下面几种:

  • 左-右的动作命令,例如移动命令h和l。
  • 上-下的动作命令,例如移动命令j和k。
  • 单词动作,例如w/W,用于文本操作的场景。例如dw,执行删除一个单词的命令。
  • 文本对象的动作命令,文本对象定义了一种字符串范围,Vim为每种文本对象定义了不同的动作命令,用户可以很灵活的利用这些动作命令选择一个字符串范围提供给操作符执行操作。下面一节有对文本对象的详细介绍。
  • marks(3.20节 标记)或jumps,用于在文件中跳转的场景。
  • 其他动作命令,主要是’%’或者’[’/‘]’为前缀的动作命令。

3.11 文本对象及动作命令

文本对象是Vim操作文本的实体,Vim提供多种这样的实体概念,这些实体包括一个单词、一个句子、一个段落等,或者是小括号()、中括号[]、大括号{}、单引号’’、双引号””、尖括号<>、反单引号``等闭合字符中的内容,甚至还包括HEML和XML中的标签。每个这种文本对象对应一个单字符命令,例如,代表单词的字符为w。

该功能需要Vim的+textobjects属性的支持。

文本对象的动作命令设计到两个前缀字符—i和a。其中i的inner的缩写,表示内部的选择;a是all的缩写,表示选择文本对象的所有,包括对文本对象边界字符的选择。这两个字符可以分别和文本对象所对应的字符进行组合成为动作{motion},再配合前面讲的操作符,组成一个操作命令。

文本对象的选择命令一般用在两种模式下,一种是在正常模式下执行{count}operator{count}{motion}(3.10节 操作符)的操作;另一种是可视模式下选择文本对象,然后对选中的内容进行操作,v{count}{motion}operator。下面在可视模式下的例子:

当插入符在一个单词中的任意一个字符时,按下viw,则这个单词被选中,用户可以执行d或者y操作符等。如果按下vaw,则单词及其后面的空格都被选中。对于有闭合字符的字符串,以小括号为例,vi(选中小括号中的内容,va(小括号也被选中。表3.4 列出了文本对象动作的绝大部分实例:

下表是操作符d加文本对象动作的操作命令:

3.12 substitute命令

Vim中的替换命令是非常常用和重要的一个功能,下面是它的格式:

:[range]s[ubstitute]/{pattern}/{string}/[flags] [count]

其中[range]定义替换范围,s是substitute命令的简写,{pattern}是匹配目标字符串的样式(一个正则表达式实例)用来匹配将被替换的内容,{string}是所替换的字符串,[flags]是替换的控制标志,[count]是替换目标字符串的次数,以行为单位。这里需要注意替换范围的控制:

  • 既不提供[range]也不提供[count]参数时,只在当前行执行替换命令。
  • 即提供[range]又提供[count]的时,替换范围是以[range]的最后一行为开始的[count]行。
  • 不提供[range]只提供[count]的时,替换范围是从当前行开始替换[count]行。

3.13 批量操作

有时候需要在多个文件中执行同样的命令,比如需要在多个打开文件中设置某些选项,但不需要对所有的打开文件都进行设置。再比如在多个文件中对某个字符串进行替换。批量操作可以选择多个要进行操作的文件,然后统一执行某个命令。常用的批量操作命令有:bufdo/:windo/:tabdo/:argdo等,这几个命令都可以对多个buffer(或文件)同时操作,唯一的差别就是选择多个文件的方式的不同,下面是分别对这4个命令详细的介绍:

1. bufdo

在当前Vim会话中的每个buffer中执行同样的命令,可以通过:ls/:buffers/:files命令查看当前Vim会话有哪些buffer(有很多第三方插件也可以做的,并且操作buffer更简单,例如bufexplorer,3.18.2.c节有介绍),命令的格式为:

:[range]bufdo[!] {cmd}

用:ls命令列出buffer列表,可以查看每个buffer的编号,所以可以用这些buffer编号指定[range]参数,当然这个参数可以省略,代表对所有buffer生效。[!]声明在未保存修改的情况下继续执行bufdo命令。{cmd}定义要执行的命令,但不能是删除或添加buffer的命令。可以使用’|’字符顺序执行更多的命令。一般要加上’!’,或者用’|’符号连接:update命令,否则因为修改内容未被保存导致:bufdo命令被中断,后面的buffer不能被操作。

2. windo

windo对当前tab中所有的窗口进行批量操作,格式是:

:[range]windo {cmd}

[range]表示窗口范围,可以省略,{cmd}是要执行的命令,但不能是打开或关闭窗口或者给窗口重新排序。可以使用’|’字符顺序执行更多的命令。

3. tabdo

在每个tab中执行相同的命令,格式为:

:[range]tabd[o] {cmd}

[range]指定tabdo的操作范围。tabdo中的o可以省略。{cmd}是要执行命令,但不能是打开或关闭tab或者给tab重新排序。使用:tabs命令查看当前tab列表。可以使用’|’字符顺序执行更多的命令。需要注意的是在每个tab中只对当前的窗口生效。

4. argdo

argdo用来自由选择一些文件进行批量操作。在进行任何操作之前要通过:argadd或:args *.x命令添加文件路径到argment列表中。默认情况下argment列表是Vim初始化时所打开的文件。argdo的格式与bufdo类似,如下:

:[range]argdo[!] {cmd}

[range]指定操作范围,也可以省略。[!]声明在未保存修改的情况下不中断argdo命令。{cmd}代表要执行的命令。使用:args命令查看当前的argment列表。可以使用’|’字符顺序执行更多的命令。这里{cmd}不能是改变argment列表的命令。

5. 例子,使用bufdo命令在所有的buffer中把cat替换成dog

:bufdo %s/cat/dog/g | update

:bufdo! %s/cat/dog/g
:wall

其中%s/cat/dog/g是替换命令,’%’声明在整个文件中进行替换,’|’声明subtitute命令执行完成后还有执行其他命令,这里是:update。这里:update命令是必须的,否则bufdo在第一个buffer中执行完成后,可能由于未保存修改会导致执行失败,其他的buffer得不到执行的机会。

第二种方法是先用bufdo命令进行修改但不保存,修改完成后用:wall命令对所有buffer执行保存操作。

3.14 自动命令(autocmd)

自动命令是在Vim会话中发生某个事件的时候自动执行某些命令序列或函数,就像c程序中的callback。例如读一个文件时可以捕获一个BufRead事件,把它定义到autocmd中可以执行自己的命令或函数。

自动命令看起来功能非常强大,但是它可能导致无法预料的副作用,所以使用时要小心谨慎。官方在帮助文档中给出了一些建议,具体请查询:h autocmd第一节Introduction。

自动命令的格如下:

:au[tocmd] [group] {event} {pat} [nested] {cmd}

其中

  • :au[tocmd]声明该条命令是自动命令。
  • [group]声明当前autocmd所在的组,autocmd允许把一系列autocmd命令存放在一个组中。如果不提供组名,Vim使用默认的group,默认group没有组名,所以你不能单独执行默认组,除非执行:doautoa[ll]命令。可以使用:augroup命令定义新的组。
  • {event}声明触发该autocmd命令所需要的事件,在一个autocmd中可以包含一个或多个事件,用逗号做为分隔符。帮助文档autocmd.txt的第5节 Events列出了Vim支持的所有事件。
  • {pat}定义{cmd}的执行范围,指定哪些文件类型需要在遇到{event}时才执行后面的{cmd},可以指定多个文件类型,用逗号做为分隔符。
  • [nested]用于命令嵌套。例如你在BufWrite事件中执行:write命令,这会导致BufWrite事件递归的发生,一般Vim不会执行这组自动命令。如果一定要执行则需要使用[nested]关键字进行声明,Vim限制递归最多嵌套10层。
  • {cmd}声明要执行的命令。

定义自动命令的一般步骤:

1. 指定一个组名

:augroup mine

2. 删除组中所有的自动命令

:autocmd!

3. 定义新的自动命令

au BufNewFile,BufRead *.html set tabstop=4 

4. 完成该组自动命令的定义

:autogroup END

例子,定义一个自动命令,在Vim退出时保存所有未保存的修改,但是略过只读文件,下面是实现该功能的代码清单:

function! SaveFile()if filewritable(bufname("%")) && getbufvar(“%","&modified") “如果文件是可写的并且’modified’选项被设置过,则执行write命令writeendif
endfunctionfunction! SaveAllFiles()brewind!let s:count = 0while bufnr("%") <= bufnr(“$") “只对buffer number范围内buffer执行SaveFile()函数call SaveFile()bnext “跳转到下一个bufferif s:count > bufnr("$")breakendiflet s:count += 1endwhile
endfunctionaugroup savemyfiles “定义自动命令组au! “清除该组中以前的autocmdsau QuitPre *.c,*.h,*.txt,*.sh,*.py,*.vim call SaveAllFiles() “定义哪些类型的文件需要退出时自动保存
augroup END “声明该自动命令组的结束

在QuitPre事件到来时,调用SaveAllFiles函数。这里SaveAllFiles函数实现了遍历当前Vim会话中所有的buffer,为每个buffer调用SaveFile函数,如果buffer被修改过并且所对应的文件是可写的,那么就对这样的buffer执行:write命令。

查看当前自动命令的一些方法:

  • 查询Vim当前会话所有的自动命令:au[tocmd]
  • 查询组group中的自动命令:au[tocmd] group
  • 查询group中指定事件的自动命令:au[tocmd] [group] {event}
  • 查询{pat}所对应的文件类型的自动命令:au[tocmd] * {pat}

Vim还支持手动执行autocmd,使用:do[autocmd]命令,命令格式如下:

:do[autocmd] [<nomodeline>] [group] {event} [fname]

有时候用户想要禁用某个或某些事件的自动命令,通过设置’eventignore’选项禁用autocmd所对应的某些事件,该选项是一个列表,列表中每一项对应一个事件的名称,但是自动命令中的其他事件还是有效的。如果临时禁用所有的自动命令(类似于onshot的操作),使用:noautocmd命令,它执行时设置’eventignore’选项为all,禁止所有的事件。

3.15 筛选命令

在命令行模式,’!’前缀告知Vim执行外部命令,外部命令完成的操作是读入在Vim中选中的内容通过标准输入发送到外部程序,外部程序运行的结果通过标准输出返回到Vim,然后替换之前选择的内容。如果不选中任何内容,可以通过:read命令读入。

例子,通过筛选命令添加当前目录的所有文件名:

或者用:read命令读取目标目录列表:

:read !ls .

3.16 了解vim内置选项

Vim内置选项是Vim功能控制的开关,通过他们实现对Vim基本功能的定制,例如打开文件时要显示文件的行号,需要用到’number’选项。在8.0版本中支持391个选项,一般通过set命令进行设置。

1. 操作方法

a. 显示所有与默认值不同的选项

:set

b. 显示所有选项,但不包括和终端相关的选项

:set all

c. 设置和取消选项

设置选项

:set {option}

重置选项

:set no{option}

d. 反转选项

:set {option}!

或者

:set inv{option}

e. 查看选项当前值

:set {option}?

f. 恢复选项默认值

:set {option}&

g. 添加选项中的子选项

:set {option}+=x

h. 删除选项中的子选项

:set {option}-=x

i. 选项只在当前buffer中生效

:setlocal {option}

j. 同时设置多个选项

:set ai nosi sw=3 ts=3

2. 重要的内置选项

a. ‘compatible’

设置compatible声明Vim对Vi兼容,使Vim的行为更像Vi。设置’nocompatible’时,可以使用Vim很多改进的和Vim独有的功能,Vim在发现vimrc或gvimrc文件时设置该值。Vi和Vim的不同可以通过:help vi-differences查看。

b. ‘runtimepath’

Vim初始化时扫描’runtimepath’所给出的路径,并加载这些路径中的Vim插件。在大多数系统中,Vim一般会扫描下列几个路径:

  • 家目录下的.vim目录,$HOME/.vim
  • 家目录下的$HOME/.vim/after目录
  • Vim安装时的共享目录$VIM/vimfiles
  • Vim共享目录的after目录,$VIM/vimfiles/after
  • Vim的发布目录$VIMRUNTIME

上列的环境变量可以在Vim命令行通过:echo命令查看,例如查看$VIM的值执行:echo $VIM命令。

c. ‘hidden’

该选项用来控制vim中buffer被换出时的行为,buffer的状态分为3种active,hidden,inactive,

  • active是buffer在窗口中显示时的状态。
  • hidden是buffer没有被显示但是仍然在内存中的状态。
  • inactive是buffer不被显示也没有任何内容的状态,但是它的选项被Vim保存的一种状态。

当不设置’hidden’选项时,不被显示的buffers将被卸载,它们的状态为inactive;当设置’hidden’时,不被显示的buffers仍然存在于内存中,这时候即使buffer中的修改未被保存,用户仍然可以浏览其他的buffer。

一种特殊的情况是,用户并未设置’hidden’同时也没有设置’autowrite’选项,但是用户在浏览buffer时使用了’!’符号,之前的buffer被强制换出了,那么它的状态会被Vim置为hidden。

例如,在修改一个buffer后未保存,紧接着执行:bnext!命令,buffer自动进入hidden状态。

d. ’modeline’

vim允许在文件的最后部分设置选项,可以实现只针对某个文件相关选项的个性化定制。在打开这样的文件时,vim会读入这些设置,使Vim合适的显示和编辑该文件。例如可以在vim的脚本文件的最后一行添加modeline设置:

" vim:tw=80:ts=4:et:ft=vim:

vim声明本行是modeline行,需要注意的是vim三个字符前面必须有一个空白字符。tw是’textwidth’选项的缩写,代表每行文本的宽度。ts是’tabstop’选项的缩写,表示一个制表符的占位宽度。et是’expandtab’选项的缩写,表示输入制表符时,用tabstop个空格代替。ft是’filetype’选项的缩写,这里设置文件类型为vim。在vimrc中设置’modeline’选项使能modeline,’modelines’选项设置了文件中有效的modeline行数。

另外,每种文件类型的modeline要用相应的注释方法进行注释,否则影响代码的编译或运行。

详情请参考:help modeline。

e. ‘encoding’

‘encoding’选项用于Vim内部处理文本时所用的编码格式,例如buffer、寄存器、表达式中的字符串、viminfo文件等。

f. ‘fileencoding’ & ‘fileencodings’

‘fileencoding’用于实际文件读写时使用的编码格式,在Vim写入文件时,如果为空则使用’encoding’的值。

在读入文件时,’fileencoding’会被设置为’fileencodings’其中一项,’fileencodings’选项表示了一个编码列表,在打开文件时提供适当的值。如果’fileencodings’列表中没有合适的选项,’fileencoding’会被设置为空,这种情况下使用’encoding’的值。另外,在’fileencodings’为空时,不会修改’fileencoding’的值。

g. ‘coptions’

coptions的值由一系列字符标志组成,特定字符代表Vim是否兼容Vi中某个功能,设置某标志时则是对Vi某个功能的兼容,反之则不兼容。当设置’compitable’选项时coptions的默认值包含所有的标志,当重置’compitable’选项时,默认值为”aABceFs”.

h. ‘number’

设置该选项时,Vim在窗口左侧显示buffer行号。

i. ‘backspace’

通过该选项控制<BS>、<Del>、CTRL-W和CTRL-U等按键在插入模式下的行为。它包含3个参数

j. ‘history’

用于设置命令行和搜索命令’/’的历史记录数,默认是50,最大可以设置到10000。

h. ‘fileformat’

设置文件的编码格式,详情请参考4.5.6节 文本编码格式及转换。

3.17 快捷键映射

按键映射在Vim中是非常常用的功能,用户可以定义自己的快捷键,并且可以定义只在某种模式下生效。映射快捷键的格式如下:

{cmd} {attr} {lhs} {rhs}

{cmd}表示使用哪个map命令,可以是map, nmap, vmap, imap, cmap等。{attr}表示一些特殊的的参数,对map命令的行为加以限制,这些参数包括:"<buffer>", "<nowait>", "<silent>", "<special>", "<script>", “<expr>”,“<unique>”,它们必须紧跟map命令之后,用空格隔开。可以添加一个或多个{attr},顺序没有限制,用逗号作为分隔符。

{lhs}表示一系列按键,它用于触发map映射,执行{rhs}中的命令。

{rhs}表示一系列命令,在用户按下{lhs}定义的按键后,执行这些命令。

1. 不同模式中的按键映射

a. map/nmap/imap/vmap/cmap

map命令可以实现在三种模式下的下的映射,分别是正常模式、可视模式、操作待决模式;nmap表示映射只在正常模式下有效;imap表示映射只在插入模式下生效;vmap表示只在可视模式下生效;cmap表示只在命令行模式下生效。

例如,在正常模式下执行一个xyz命令,可以这样实现:

:nmap xyz :echo “Hello World”<CR>

nmap对应前面的{cmd}部分;xyz对应{lhs}部分;:echo “hello world”<CR>对应{rhs}部分,其中<CR>表示回车确认echo命令的执行。

b. noremap/nnoremap/vnoremap/inoremap/cnoremp

noremap与map不同的是它禁止对{rhs}部分进行映射扩展,禁止进行递归映射。那么什么是递归映射?它跟Vim允许多重映射有关系,我们仍然用上面hello world的例子,定义以“xyz”分别为{lhs}和{rhs}的两个映射:

:nmap xyz :echo “hello world”<CR>
:nmap abc xyz

vim会在执行abc这个映射的时候判断xyz是否是另一个映射的{lhs},如果是那么Vim会递归展开xyz的映射,也就是:echo命令,所以如果执行abc的时候,实际会执行到:echo命令。那么这时候问题来了,你映射的{lhs}可能只是另外一个映射{rhs}的一部分,Vim递归展开时会导致最终执行的命令非你所愿,下面是另外一个例子:

:nmap <F2> diw
:nmap di dd

根据上面的两个映射,在按下<F2>键后Vim执行diw,这时di展开为dd,最终执行ddw的操作,dd是删除当前行的命令,但是我们映射<F2>的本意是删除一个单词。为了解决这个问题使用nnoremap命令对<F2>进行映射:

:nnoremap <F2> diw

nnoremap表示不再对{rhs}部分执行展开操作。

c. unmap/nunmap/iunmap/vunmap/cunmap

unmap用于解除map命令的映射关系,格式为:

{cmd} {lhs}

这些命令和上面的命令是对应的,不同的前缀代表不同的模式。仍然以上面的:nmap为例,来解除对:echo命令的映射:

nunmap xyz

如果一个映射使用了:map命令在多个模式上映射{lhs},但是用:nummap解除{lhs},则其他模式的映射仍然保留。注意{lhs}后边不能有空白字符,因为它们都会被记入{lhs},这样导致unmap不生效。unmap命令同时会影响noremap的命令实现的映射。

d. mapclear/nmapclear/imapclear/vmapclear/cmapclear

用于解除对应模式中的所有按键映射。前缀n/i/v/c相同于与第a节中的命令,不同模式下的映射对应不同的前缀,mapclear命令可以解除所有的映射。

2. 使用mapleader

mapleader是表示一个字符串,它也是Vim的一个内置全局变量,用于在用户不知道用哪些按键序列进行映射的时候,可以在一组已存在按键前加一个mapleader,尤其是在想用尽量少的按键来映射一个新的快捷键序列时非常有用,可以很容易的避免与已经存在的映射有冲突。例如,用两个字符映射上面的:echo命令:

nnoremap <Leader>e :echo “hello world!”<CR>

默认情况下mapleader是不被设置的,那么<Leader>会用斜杠””字符,所以上面的映射等同于:

nnoremap e :echo “hello world!”<CR>

在正常模式下依次按下e键进行触发。mapleader可以通过let命令修改,例如改成逗号”,”

:let mapleader = “,”

这样在使用<Leader>进行映射的时候,所有的按键序列都以“,”开头了,但是不会对之前已经定义的<Leader>映射产生影响。

3.18 Vim插件

  1. 内置插件

Vim有很多内置插件,在vim中执行:script命令可以列出Vim当前所加载的插件。可以发现大部分插件来自/usr/share/vim/vim80/目录,这就是Vim内部插件安装的根目录。在我的/usr/share/vim/vim80/目录下执行“find . “*.vim” | wc -l”命令,有1346个之多。在3.2节,我们已经介绍了$HOME/.vim目录下有几个固定名称的文件夹,Vim内置插件的目录结构是类似的,这里只介绍这些目录下一些最常用的插件。

a. ftplugin.vim

该插件通过自动命令截获FileType事件,然后获取触发自动命令时文件的后缀,根据这个后缀名扫描’runtimepath’选项中所设置的路径,把当前文件类型的相关插件加载到vim的运行环境中。

它首先构建了一个自动命令:

au FileType * call s:LoadFTPlugin()

在’filetype’选项被设置时,触发FileType事件,这种情况下调用s:LoadFTPlugin函数。在该函数中通过<amatch>获取了自动命令所匹配的文件后缀。然后执行在for语句中有最关键的一句代码:

exe 'runtime! ftplugin/' . name . '.vim ftplugin/' . name . '_*.vim ftplugin/' . name . '/*.vim'

它通过一个runtime命令加载相关文件类型的插件。以c语言源码文件为例,runtime的命令则为“runtime! ftplugin/c.vim ftplugin/c_*.vim ftplugin/c/*.vim”,所以当检测到c文件类型时,自动命令完成对c文件类型相关插件的加载。

Vim会在’runtimepath’(3.16.2.b节)选项中所列出的路径依次搜索,在我当前Vim版本中’runtimepath’选项的值为“~/.vim,/var/lib/vim/addons,/usr/share/vim/vimfiles,/usr/share/vim/vim80,/usr/share/vim/vimfiles/after,/var/lib/vim/addons/after,~/.vim/after”,它包含Vim的安装路径,也包含用户的~/.vim和~/.vim/after等目录。所以如果你在自己的家目录下创建了上面所描述的目录及插件,Vim在运行时通过ftplugin.vim插件加载了它们。

b. filetype.vim

该插件主要功能是在打开文件的时候根据文件后缀设置’filetype’选项。仍然以c代码文件为例,可以在filetype.vim中看到如下自动命令:

au BufNewFile,BufRead *.c call dist#ft#FTlpc()

打开c文件时,触发BufNewFile或BufRead事件,调用dist目录下ft.vim中的dist#ft#FTlpc()函数,该函数会设置文件类型为c。’filetype’选项被设置时触发FileType事件,在上面所提到的ftplugin.vim插件中已经实现了FileType事件的自动命令,触发该事件时加载所有c文件相关的文件类型插件。

c. netrw.vim

netrw插件主要用于在本地或网络上浏览文件夹。netrw.vim存放在/usr/share/vim/vim80/autoload/目录中,所以该插件在必要时才被加载(3.2.4节有对autoload文件夹的介绍)。

通常用Vim打开一个文件夹时,syntax/netrw.vim插件会设置浏览文件夹时的语法高亮。

另外一个插件plugin/netrwPlugin.vim,它对netrw.vim所实现的功能进行封装,通过一些自动命令实现user->vim->netrw.vim三者之间的交互。

d. ftplugin/qf.vim和syntax/qf.vim

qf.vim是和quickfix窗口相关的辅助插件,它的实现非常简单,就是设置quickfix窗口的’statusline’。syntax/qf.vim用来设置quickfix窗口的语法高亮。

e. syntax/syntax.vim和syntax/synload.vim

在执行:syntax on或:syntax enable命令时,Vim加载syntax.vim。syntax.vim定义了设置’syntax’选项的自动命令,其中的自动命令监测FileType事件,同时加载synload.vim插件,synload.vim定义了Syntax事件的自动命令。当设置’filetype’选项时,syntax.vim中的自动命令被触发,它设置’syntax’选项为相应的文件类型,这又触发了Syntax事件,在synload.vim中Syntax事件的自动命令会加载与语法高亮有关的插件。

/usr/share/vim/vim80/syntax目录中包含了大多数文件类型的语法高亮插件。

f. syntax/nosyntax.vim

移除所有的为语法高亮设置的自动命令,同时清除所有buffer的语法高亮设置。运行:syntax off命令时加载该插件。

g. colors/目录

colors目录包含Vim自带的不同颜色组合的插件,其中default.vim是默认的颜色组合插件。:colorscheme {name}命令可以切换不同的颜色组合。

2. 常用的第三方插件

a. taglist.vim

用于显示函数、类、结构体、宏、变量、枚举类型等的定义,当在TagList窗口对某个定义选择时可以自动跳到相应定义的位置,所以它是用来浏览代码的利器。

b. mru.vim

用于快速查找最近打开过的文件,它会自动保存所打开过的文件路径到家目录下的.vim_mru_file文件中,在需要的时候执行:MRU命令打开MRU窗口,选择需要的文件。

c. bufexplorer.vim

用于浏览当前Vim中的buffer列表,可以在各buffer间快速切换。

d. NERD_tree.vim

用于显示目录树。

e. FuzzyFinder

它提供快速查找buffer/file/command/bookmark/tag等内容的方法。使用该插件之前需要安装l9库,它的下载地址是https://github.com/vim-scripts/L9.git。

f. winmanager

提供窗口管理功能,可以和bufexplorer.vim、taglist.vim等插件配合使用,你可以在Vim中同时显示多个不同插件的窗口,使Vim看起来更像一个IDE。winmanager还有浏览目录的功能,这和NERD_tree.vim插件以及内置插件netrw.vim有一些功能重叠,但不完全一样。

使用第三方插件时需要注意的是,有些插件需要创建自己的显示窗口,如果用:edit命令打开其他的文件,在执行命令之前需要手动切换回真正在显示文件的那个窗口,否则你打开的文件会显示在插件的窗口中,这会弄乱显示区。

3.19 vim内置函数

vim的内置函数可以使用户更灵活的控制Vim,通过Vim脚本语言的配合内置函数定制自己理想的功能。当然可以在Vim的命令行模式进行函数调用,但是通常情况下这样使用效率并不高。由于我们主要在本文中只对Vim的基本功能进行介绍,所以不对Vim的内置函数做过多介绍,这里只是供有兴趣的同学了解一下。执行:help functions命令查看Vim所有的内置函数。

在Vim的命令行执行call命令进行函数调用,例如获取当前文件的绝对路径,可以输入下面的命令:

:call expand(“%”)

这里“%”表示当前的文件路径。

3.20 标记(mark)

它相当于书签功能,用起来非常简单。标记分为两种,当前文件内标记,多文件标记。当前文件的标记使用{a-z}26个小写字母命名,大写字母{A-Z}和10个数字{0-9}用于在不同的文件中定义标签,这是Vim内定的,不能自己定义标签名称。当需要定义标记时只要在正常模式下按m,紧接着按下上面提到的标签名称完成定义(除数字标记)。当需要跳转到相应标记时,在正常模式下按下单引号’或反引号`加标记名称即可,比如要在当前行定义标记a:

ma

代码浏览到其他行时需要到标记a处:

‘a 或 `a

列出所有的定义的标记:

:marks

删除标记a:

:delm[arks] a

删除当前文件中的所有标记。不包括{A-Z0-9}:

:delm[arks]!

多文件标记{A-Z0-9}可以永久保存在viminfo中。

特殊标记{0-9},它们不能直接被设置。’0用于存储在Vim写viminfo文件(Vim退出或执行:wviminfo命令)时的插入符位置,旧的’0值会保存在’1中,旧’1的值保存在’2中,以此类推。

3.21 会话(session)

Vim可以为一次会话保存窗口视图、buffer列表以及选项值等内容。通过’sessionoptions’选项可以选择Vim保存哪些内容。:mksession命令保存’sessionoptions’选项的指定内容到文件中,命令的原型为:

:mks[ession][!] [file]

[!]表示重写[file]所代表的文件。

[file]表示要保存的会话文件路径,省略该参数时默认在当前的工作路径创建文件名为”Session.vim”的脚本。

通过Vim的S参数读取所保存的会话文件,恢复保存Vim会话:

vim -S your_session.vim

‘sessionoptions’选项可以设置保存下面子选项所表示的内容:

  • options: 保存所有的选项和映射。
  • localoptions: 保存本地选项和映射。
  • globals: 保存以大写字母开头和包含至少一个小写字母的全局变量,只保存字符串和数字类型。
  • curdir: 保存Vim当前的工作路径。
  • sesdir: 设置session脚本所在的路径为Vim当前的工作路径。
  • winpos: 保存Vim窗口的位置(左上角坐标,用于gVim)。
  • resize: 保存屏幕尺寸,当前Vim所能显示的行数和列数。
  • buffers: 保存buffers列表。
  • help: 保存帮助窗口。
  • blank: 保存空窗口。
  • winsize: 保存每个窗口的尺寸。如果未添加help或blank选项,但是有help或blank的窗口,Vim加载会话文件后,不会包括help或blank的窗口,所以会适当的调整其他窗口的大小。
  • tabpages: 保存所有的tab页,没有设置该选项的情况下,只保存当前tab页。
  • folds: 保存代码或文本的折叠

执行:mksession时默认保存buffer列表、插入符位置、窗口布局等内容。可以用’?’(3.16.1.e节”查看选项值“)查看’sessionoptions’选项的默认值,我的Vim ’sessionoptions’选项默认值为:

blank,buffers,curdir,folds,help,options,tabpages,winsize

可以用3.16.1.g/h节所介绍方法添加或删除子选项。

3.22 quickfix

Vim的quickfix功能最初是为了加速解决编译代码时所产生的错误,不用退出Vim就能快速定位错误代码行。quickfix保存编译器输出的错误信息到一个文件中,可以跳转到每一条错误对应的代码行并快速的进行修改。

用户可以生成一个quickfix能识别的列表,然后定位列表中的每一项,列表项的格式遵循’errorformat’选项的设置。其中列表中的每一项可以作为quickfix中的一行显示在quickfix窗口中,Vim提供了很多quickfix窗口的控制命令,例如:copen命令打开quickfix窗口,:cclose命令关闭quickfix窗口。

下表是quickfix的一些常用命令:

后面在4.8.2节将介绍在quickfix窗口中显示cscope的输出结果,4.8.3节介绍在Vim中grep与quickfix结合的相关用法。

quickfix还能保存10个历史列表,用户可以很方便的切换过去所查询的内容,上表中:cnewer/:colder/:chistory三个命令实现了浏览历史查询列表的功能。

Vim甚至提供操作quickfix的API去定制自己的功能,例如getqflist函数返回quickfix当前显示的列表,setqflist函数设置quickfix的列表。

lsdyna如何设置set中的node_list_技术成长日记-Vim-3.Vim中重要的概念相关推荐

  1. vue替换全部符合’字符串_技术成长日记-Vim实用技巧-4.7查找替换

    1. 普通查找 / 向下查找 ? 向上查找 n 查找下一个目标字符串 N 查找上一个目标字符串 q/ 回溯查找历史,输入该命令后会在状态栏上方显示一个查找历史回溯窗口,如图4.1: 图4.1 回溯查找 ...

  2. 腾讯MIG实习技术成长日记集

    原创作品,出自 "晓风残月xj" 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj). 由于各种原因,可能存在诸多不 ...

  3. 2100 反弹shell无法粘贴_技术成长日记-Vim实用技巧-4.6复制/删除/粘贴

    1. vim中的复制操作 相当于unix或windows中的ctrl+c,但是只在Vim会话生效,不影响剪切板.命令格式如下: {count}y{motion} 例如复制3个单词: 3yw 其中3表示 ...

  4. linux中的c技术,基于linux下C开发中的几点技术经验总结

    最近一致致力于linux下的C开发,因为老大是某讯出来的.因此,使用的主要技术都是某讯的基本的后台架构思想. 在这段时间,学习到了很多,然后佩服某讯的技术果然很厉害. 因此,自我感觉,从头开发我们这个 ...

  5. BIOS中VT虚拟技术已经开启,但任务管理器中仍显示虚拟化已禁用

    在BIOS中打开了VT, 但是在任务管理器中却仍显示 已禁用 我的解决方法: 1.进入BIOS中,关闭VT,重启 2.然后,再进入BIOS中,开启VT,重启 3.终于....CPU虚拟化成功启用,可以 ...

  6. 计算机技术在环境工程中有哪些应用,计算机在环境工程中的应用技术

    1 计算机在环境工程中的应用概述 环境工程与计算机概况 计算机技术在环境工程中的主要应用领域 计算机网络技术在环境工程中的应用 计算机在环境工程科研与管理中的应用 计算机在环境工程计算中的应用 计算机 ...

  7. 计算机与工程建设项目结合,工程建设项目中计算机科学与技术的应用分析.doc...

    工程建设项目中计算机科学与技术的应用分析 工程建设项目中计算机科学与技术的应用分析 工程建设项目中计算机科学与技术的应用分析 前言 近些年来,科学技术不断地提高,其发展也促进了计算机科学与技术的飞速前 ...

  8. 长时间序列遥感数据处理及在全球变化、物候提取、植被变绿与固碳分析、生物量估算与趋势分析等领域中的实践技术应用

    [查看原文]长时间序列遥感数据处理及在全球变化.物候提取.植被变绿与固碳分析.生物量估算与趋势分析等领域中的实践技术应用 植被是陆地生态系统中最重要的组分之一,也是对气候变化最敏感的组分,其在全球变化 ...

  9. 中国下游处理中的浓度技术市场深度研究分析报告

    [报告篇幅]:93 [报告图表数]:144 [报告出版时间]:2021年1月 报告摘要 2019年中国下游处理中的浓度技术市场规模达到了XX亿元,预计2026年将达到XX亿元,年复合增长率(CAGR) ...

最新文章

  1. case when里的like功能 ////// 截取(substr)
  2. mysql spool csv报错_参数化之利用CSV Data Set Config从文件读取参数并关联变量
  3. 云技术概况:云计算的优点/特点/类型/服务模式
  4. pytorch——torch.backends.cudnn.benchmark = True
  5. MATLAB字符串数组中查找指定子串
  6. C语言 sprintf 函数 - C语言零基础入门教程
  7. linux c++ 函数效率,C++高精度性能测试函数
  8. HttpClientHelper的封装
  9. 软工作业PSP与单元测试训练 15100231
  10. zeppelin 配置 spark
  11. 分享一个手写轮播图的学习案例
  12. 解决systemback 无法生成超过4G的iso的问题
  13. 描述羽毛针禾及其特殊结构——“根鞘”的词有哪些呢?已经做完的项目和目前羽毛针禾面临的科学问题有哪些?
  14. 《资治通鉴》曾参三人成“真”、胡服骑射、吕不韦
  15. PHP剧影评系统的设计与实现毕业设计源码140859
  16. 【POJ3683】Priest John's Busiest Day(Special Judge)
  17. SLAM【十一】建图
  18. 《我的青春谁做主》剧中人物星座分析
  19. 来晚了,秋招五投大厂,成功拿下三家Offer,最终入职美团,分享我的美团1-4面(Java岗)
  20. 直播间实时在线人数方案

热门文章

  1. 洛谷_3975 [TJOI2015]弦论(后缀自动机)
  2. lamp mysql开机自启_CentOS 程序开机自启动方法总结
  3. 艺赛旗联合创始人胡立军:咨询机构、CIO和用户眼中的RPA「理想型」
  4. 【OpenGL】查看显卡对OpenGL的支持程度
  5. Android Service的启动过程
  6. 基于边缘计算网关的PLC设备远程监控系统
  7. python 主力资金_邢不行 | 量化投资中如何计算机构、主力、散户资金流数据【视频】...
  8. 常用的excel公式备忘
  9. win7计算机任务栏颜色怎么,如何修改win7电脑下方任务栏的颜色?
  10. 企业微信海外版此前将名称改为 “Wecom”,腾讯打算将其设置为微信的潜在替代方案