✨✨所属专栏:Linux✨✨
✨✨作者主页:嶔某✨✨
vim的三种常用模式
分别是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode)
各模式的功能区分如下:
- 正常/普通/命令模式(Normal mode) 控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode。
- 插入模式(Insert mode) 只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。该模式是我们后面用的最频繁的编辑模式。
- 末行模式(last line mode) 文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。 在命令模式下,shift+: 即可进入该模式。要查看你的所有模式:打开vim,底行模式直接输入
:help vim-modes
vim的基本操作
进入vim
vim code.c
正常模式切换为插入模式
- 输入a:在当前字符的下一个字符进入插入模式
- 输入i:在当前字符进入插入模式
- 输入o:另起一行进入插入模式
插入模式切换为正常模式
目前处于插入模式,就只能一直输入文字,如果发现输错了字,想用光标键往回移动,将该字删除,可以先按一下「ESC」键转到正常模式再删除文字。当然,也可以直接删除。
正常模式切换到末行模式
- 「shift + ;」其实就是输入「 : 」
退出vim及保存文件
在正常模式下,先进入末行模式输入:
- w:保存文件,但不退出
- q:退出
- wq!:强制保存并退出
vim正常模式命令集
移动光标
- vim可以用键盘上的上下左右键来控制光标,但正规的vim是用小写的字母「h」、「j」、「k」、 「l」、分别控制光标左、下、上、右移动一格
- 按「G」:移动到文章最后
- 按「gg」:移动到文章开头
- 按「$」:移动到所在行的行尾
- 按「^」:移动到所在行的行首
- 按「w」:光标跳到下一个字符串的开头
- 按「b」:光标回到上个字符串的开头
删除文字
- 「x」:每按一次删除光标所在位置的一个字符
- 「# x」:删除光标所在位置后面(包含自己)的 # 个字符
- 「dd」:删除光标所在行
- 「#dd」:从光标位置开始删除 # 行
复制
- 「yy」:复制光标所在行到缓冲区
- 「yw」:复制光标所在位置到所在字符串末尾的字符到缓冲区
- 「#yw」:复制#个字到缓冲区
- 「p」:将缓冲区内的字符贴到光标所在位置。注意:所有与“y”有关的复制命令都必须与“p”配合才能完成复制与粘贴功能
替换
- 「r」:替换光标所在处的字符
- 「R」:替换光标所到之处的字符,直到按下「ESC」键为止。
撤销上一次操作
- 「u」:如果您误执行一个命令,可以马上按下「u」,回到上一个操作。按多次“u”可以执行多次回复。
- 「ctrl + r」: 撤销的恢复(撤销你的撤销)
更改
- 「cw」:更改光标所在处的字符到字符串尾部,并进入插入模式
跳至指定行
- 「ctrl」+「g」:列出光标所在行的行号。
- 「#G」:光标移动至第 # 行行首,例如,「15G」,表示移动光标至文章的第15行行首。
vim末行模式命令集
在使用末行模式之前,请记住先按「ESC」键确定已经处于正常模式,再按「:」冒号即可进入末行模式。
列出行号
- 「set nu」: 输入「set nu」后,会在文件中的每一行前面列出行号
跳到文件中的某一行
- 「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行行首
查找字符
- 「/关键字」: 先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按 「n」会往后寻找到您要的关键字为止。
- 「?关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直 按「n」会往前寻找到您要的关键字为止。
保存文件
- 「w」: 在冒号输入字母「w」就可以将文件保存起来
离开vim
Linux项目自动化构建工具make/Makefile
- 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
- makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
- make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一 种在工程方面的编译方法。
- make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建
实例
比如我们有一个code.c文件要将它预处理、编译、汇编为 .o文件可以在Makefile里输入:
code:code.ogcc -o code code.o
code.o:code.sgcc -c code.o code.s
code.s:code.igcc -S code.s code.i
code.i:code.cgcc -E code.i code.c
上面的意思就是将code.c文件处理成可执行文件,code依赖code.o这是依赖关系,第二行的命令就是依赖方法
make是如何工作的,在默认的方式下,也就是我们只输入make命令。
- make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
- 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“code”这个文件, 并把这个文件作为最终的目标文件。
- 如果code文件不存在,或是code所依赖的后面的code.o文件的文件修改时间要比code这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成hello这个文件。
- 如果code所依赖的code.o文件不存在,那么make会在当前文件中找目标为code.o文件的依赖性,如果找到则再根据那一个规则生成code.o文件。(这有点像一个堆栈的过程)
- 当然,你的C文件和H文件是存在的啦,于是make会生成 code.o 文件,然后再用 code.o 文件声明make的终极任务,也就是执行文件code了。
- 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
- 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错, 而对于所定义的命令的错误,或是编译不成功,make根本不管。
- make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起, 我就不工作啦。
项目清理
- 像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行, 不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重新编译。
- 但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。
- 由于伪目标不对应实际文件,make 在处理伪目标时不会根据文件的存在与否、时间戳等来判断是否需要执行相关操作,而是只要在命令行中指定了要执行该伪目标,make 就会执行与之关联的命令序列。
.PHONY:
clean:@rm -f *.i *.s *.o@echo "remove"
ps:命令前面加@在执行的时候就不会回显
进度条小程序
第一版:没有和网络联系起来
#include "process.h"
#include <string.h>
#include <unistd.h>
#define style '#'void process_v1()
{char buff[101] = { '0' };const char* stat = "|/-\\";int len = strlen(stat);for(int i = 0; i < 101; i++){printf("[%-100s][%d%][%c]\r",buff,i,stat[i%len]);fflush(stdout);buff[i] = style;usleep(50000);}printf("\n");
}
第二版:
#include<stdio.h>void process_v2(double total, double cur)
{char buff[101] = { '0' };const char* lable = "|/-\\";int len = strlen(lable);int num =(int)(cur*100/total);for(int i = 0; i < num; i++){buff[i] = '#';}double rate = (cur*100)/total;static count = 0;printf("\033[32m[%-100s][%.1f%%][%c]\033[0m\r",buff,rate,lable[count%len]);count++; fflush(stdout);
}int main()
{int t = 1024;int ad = 0;while(ad <= 1024){process_v2(t,ad);ad++;usleep(5000);// 模拟网络下载}printf("\033[32m\n\rcomplete!!!\033[0m\n");return 0;
}
本期博客到这里就结束了,如果有什么错误,欢迎指出,如果对你有帮助,请点个赞,谢谢!