首页
归档
友情链接
关于
Search
1
在wsl2中安装archlinux
105 阅读
2
nvim番外之将配置的插件管理器更新为lazy
78 阅读
3
2018总结与2019规划
62 阅读
4
PDF标准详解(五)——图形状态
40 阅读
5
为 MariaDB 配置远程访问权限
33 阅读
软件与环境配置
博客搭建
从0开始配置vim
Vim 从嫌弃到依赖
archlinux
Emacs
MySQL
Git与Github
AndroidStudio
cmake
读书笔记
编程
PDF 标准
从0自制解释器
qt
C/C++语言
Windows 编程
Python
Java
算法与数据结构
PE结构
Thinking
FIRE
菜谱
登录
Search
标签搜索
c++
c
学习笔记
windows
文本操作术
编辑器
NeoVim
Vim
win32
VimScript
emacs
linux
文本编辑器
Java
elisp
反汇编
OLEDB
数据库编程
数据结构
内核编程
Masimaro
累计撰写
314
篇文章
累计收到
31
条评论
首页
栏目
软件与环境配置
博客搭建
从0开始配置vim
Vim 从嫌弃到依赖
archlinux
Emacs
MySQL
Git与Github
AndroidStudio
cmake
读书笔记
编程
PDF 标准
从0自制解释器
qt
C/C++语言
Windows 编程
Python
Java
算法与数据结构
PE结构
Thinking
FIRE
菜谱
页面
归档
友情链接
关于
搜索到
24
篇与
的结果
2022-05-25
vim 从嫌弃到依赖(13)——motion 进阶
在最开始的时候我们介绍了一些vim中的motion 包括如何在字符间、单词间、行间以及多行间移动。·但是motion中的内容可远不止我们介绍的这些,平时用到的也远不止之间介绍的那些。之所以没有一次介绍完,主要是不想搞那么复杂,一次性全都介绍完那么篇幅会显得很长,而且显的很复杂。vim入门最重要的一步就是用起来,如果初学者因为看到入门类的文章出现一堆不知道什么意思的操作命令,肯定会被吓跑的,也就无法体会到vim的魅力了。像这种进阶类的内容我想将它们放到后面,等各位小伙伴能熟练使用vim完成编辑任务之后再来考虑通过进阶内容进一步提高使用效率。vim屏幕行与实际行vim中有一个wrap 设置,表示一行文本超过多少行就会自动折行,这样就不会出现在一个屏幕上显示不全的问题了。在最开始配置neovim 的基础配置的时候已经展示过该如何启用wrap 设置,这里就不再演示了在启用自动折行的设置后,如果一行文本字符数超过设置的值会自动折行。在屏幕上显示为多行。当我们开启了显示行号的设置之后很容易区分。实际行在vim中只显示一个行号,而在屏幕上会显示多行。我们知道行间移动使用的是j、k, 他们是在实际行之间移动,如果想要在屏幕行间移动,可以使用 gj、gk。一般针对行相关的操作,只需要在前面加上g 就可以改成在屏幕行之间的操作。例如g0 是移动光标到屏幕行行首。g$ 移动到屏幕行行尾。他们与普通的行移动motion 用法类似,即可以配合数字表示重复,也可以配合operator 来执行相应的操作。单词与字串在vim中一个单词由字母、数字、下划线或者其他非空白字符组成,单词间以空白字符分割。而字串是由非空白字符序列组成。这个感觉可能很抽象,但是多多联系和尝试应该就很容易明白了。字串间的移动使用大写的W, B。下面来看一个例子e.g. there's a nvim config file in "~/.config/nvim/init.lua"我自己总结如下:区别单词应该以字母、数字、其他非空白字符进行分类字串仅仅以空白字符为区分同一类型的字符序列组成的部分作为一个单词。例如上述句子由字母、空白字符和其他非空白字符(. ' ~ /)组成, e.g. 后面是一个空白字符,因此它被划分为一个字串,而它自身经历了字母、非空字符、字母、非空字符的序列,所以vim将他们划分为了4个单词。如果这样比较麻烦,那就简单的记住:字串比单词要长,不需要细粒度的移动,可以用字串间移动。本次就说到这里了,各位可以配合一下最开始的几篇文章,配合使用,巩固一下motion相关使用。
2022年05月25日
16 阅读
0 评论
1 点赞
2022-05-18
vim 从嫌弃到依赖(12)——打开及保存文件
在前几篇文章中,我们从vim各种模式的使用着手介绍了vim如何进行文本本身的编辑。也通过缓冲区列表的介绍了解到了vim是如何进行打开文件的管理。这篇我们将会着眼于文件的打开和保存的基本操作。通过这篇的阅读,我们可以正式开始尝试将vim用做代码编辑器,而不再是像之前那样作为普通的文本编辑器。开始前的准备先来介绍一下vim的工作目录的概念。我们知道进程都有自己的工作目录,后续需要操作某个目录的时候,可以根据这个工作目录使用相对路径。这样的好处是比较灵活,只要我们的文件按照一定的规则进行组织,后续可以更换程序可执行文件所在路径而不用更新代码。vim自己也有一个工作目录的概念,可以通过:pwd 来查看当前vim的工作目录是哪个,一般来说我们是从shell中的哪一个目录中进入的vim,那么vim的工作目录就是哪个。为了展示vim是如何进行目录和文件管理的,这里我准备通过我之前在github上托管的自己的vim配置文件来进行演示,nvim-config 各位小伙伴可以下载进行实验,以便达到与教程保持相同效果。也可以采用自己的实际项目进行实验。这里我多说一句,我并不推荐各位采用这个配置,第一个原因在于这个配置并没有完全完成,算是一个半成品。第二个原因是这个配置并不能完美的符合各位的工作流和工作习惯。我们学习vim、学习vim的配置主要是为了结合自己的工作习惯和工作流形成一套符合自己习惯的操作方式,并不推荐大家照搬里面的配置。第三个原因是,在后续我想写一系列的从0开始配置vim的文章,帮助大家完成自己的配置。edit命令打开一个文件可以通过:edit {filename} (或者简写为 :e ) 。如果filename采用绝对路径,那么打开的就是绝对路径所对应的文件,如果是相对路径,那么就可以打开相对与vim工作目录的文件。例如我们想打开项目中的基础配置文件lua/basic/settings.lua,就可以执行:edit lua/basic/settings.lua。根据我们前面所学的内容,vim的命令模式是支持自动补全的,我们可以通过tab来快速补全路径假设现在已经打开了这个文件,我想打开它同级目录下的keybinds.lua 来配置快捷键的话,我要同样的输入:edit lua/basic/keybinds.lua。本来我已经打开了与它同级目录中的 settings.lua 了,我为了打开keybinds.lua 要输入这么大一堆,如果我能以当前settings.lua 的路径作为相对路径就好了。vim 在命令行中提供了一个% 作为活动缓冲区的完整路径。我们在直接介绍命令模式的时候,%是作为范围表示当前打开的整个文本。这里它作为路径参数的话,表示的是当前打开文本的完整路径。我们可以通过 :edit %<Tab> 来自动显示整个路径,然后通过<C-w> 来删除单词,直到删除到当前目录,然后再输入keybinds.lua 就可以了 用这种方法是简单了点,但是最后还要删除个文件名,上面我们按了3次` ,也挺麻烦的。有没有什么方法可以直接定位到对应的目录,让我直接输入文件名呢?可以通过 在%的后面加上:h 来自动去掉文件名,即输入:edit %:h` 来自动出现对应的目录。这个功能还是挺有用的,但是需要输入这么多内容,为了简化它你肯定也想到了,要给它配置快捷键。这里还是留到以后再讲解它的使用。find命令即使:edit 命令有% 这种操作来简便输入,但是在打开其他目录中的文件时仍然需要输入完整的目录和文件名,这个操作也是挺繁琐的。操作系统中,有一个PATH 环境变量,输入命令的时候,他会在PATH 所指定的目录中查找对应命令。vim中也有类似的概念。vim中可以使用:find,根据输入的文件名打开文件。但是使用:find 的前提是配置path 变量。它们合作完成打开文件的操作,与环境变量的用法类似。可以输入:set path+=./** 将当前工作目录以及它下面的所有子目录。然后可以直接输入:find keybinds.lua 打开这个文件了。你可能会问,如果项目中有相同的文件名呢,这个项目里面没有同名文件,这里我们在lua/basic 目录中新建一个init.lua 这样它就与根目录下的init.lua 相同了。我们输入:find init.lua ,它会打开当前文件所在目录附近的同名文件。例如如果当前打开的文件在lua/basic 目录中,那么它会打开nvim-config/lua/basic/init.lua ,如果当前打开文件在nvim-config 中,它会打开nvim-config/init.lua。也可以在输入完init.lua 之后,按下<Tab> 它会提示所有匹配到的文件。我们可以指定位置的文件打开。在我们不断使用tab来匹配会出现3个匹配项:init.lua、./init.lua、./lua/basic/init.lua。他们分别对应着上面所说的那个匹配的文件,以及其他两个不同位置的文件。vim自带的目录管理工具在一般的ide中,左侧或者右侧会以树的形式显示项目中的目录。vim中也有这样的功能。它是vim提供的一个名为netrw 插件。我们打开一个目录就可以看到,它在窗口中显示该目录中的文件结构。它与普通的缓冲区窗口一样,可以通过motion 操作来移动光标。也支持命令行模式,但是这个缓冲区是不可修改的,也无法保存。在该窗口中,随意选择一行按下回车,如果选择的是一个文件,那么它会打开该文件,如果是目录那么窗口中则会进入该目录并显示目录内容。我们可以像打开一个普通的文本文件那样打开一个目录,二者的区别仅仅在于显示的内容不同,某些行为不同而已。如果当前已经打开了一个文件,我想再继续显示这个目录呢?相信各位小伙伴已经猜到了,既然可以以打开普通文件的方式打开新的目录,那么我使用:edit 命令,在后面加入目录路径是不是就可以了。经过实验,确实是这样呢。看到没,vim就是这样,一旦理解了它的逻辑,很多东西自己就能猜到。当然vim也提供了:Explore 专门用来显示目录结构。它可以简写为:E 后面不加任何东西可以打开当前文件所在目录,也可以加上路径打开指定目录。如果我们想要像普通编辑器那样将目录结构放到左边怎么办呢?套用打开文件的方式,各位肯定能想到使用:vsplit 加上目录名。vim也提供了一组命令:Sexplore和:Vexplore 分别在水平和竖直方向打开目录。vim自带的这个目录管理工具最大的问题是我通过回车键从里面选择一个之后,会在当前窗口打开一个新的缓冲区,并且把目录树给覆盖了,这个时候我们可以快速按下<Ctrl + Shift>^ 来在新打开的缓冲区和目录树之间切换。除了浏览目录结构以外,也可以利用该插件进行文件和目录的创建、删除、修改、重命名等操作,例如,使用% 来创建文件, d 来创建目录,R 重命名或者移动目录和文件,使用 D 来删除一个目录或者文件vim自带的目录管理工具虽然提供了各种功能,但是并不是特别好用,我们有众多的第三方工具可以使用。这个留着等到介绍配置的时候再说。一次性讲太多了显得太杂,而且我想用一个悬念留住各位读者,也用它来吸引新的读者,这也算是我一点小小的私心吧。写入文件的一些小技巧写入不存在的目录中我们在原项目的基础之上打开一个新的有不存在目录的文件,例如:e random/111/test.txt。我们成功的进入了vim的编辑界面,我们也可以进行编辑,但是一旦执行写命令的时候,发现vim会提示目录不存在。它保存文件需要将文件保存到一个已经存在的目录中。我们可以退出vim,然后使用mkdir 来新建目录。这个是下下策,之前输入的内容全丢失了,再重新来一遍实在是令人恼火,不瞒各位,我之前就是这么干的,所以我养成了,新打开一个文件就立马执行:w 的习惯。还记得之前讲过怎么在vim中执行shell命令吗,不想退出vim,又想在保存前创建目录,可以使用这招, :!mkdir -p random/111, 然后再执行写入。或者可以灵活的使用在前面介绍的:%h 来快速补全相对路径强制以root用户写入文件有时候我们使用vim打开了系统文件,例如打开了/etc/hosts 文件,但是保存的时候意识到忘了加sudo 了,导致无法写入,我以前的办法是先退出,然后再用root权限打开,这样就导致之前输入的内容全都丢失了,幸亏我养成了前面说的那个习惯,打开文件之后的第一步就是执行:w,在学习了vim的命令模式之后,估计各位小伙伴已经有思路来解决这个问题了。我们以当前文件内容作为命令输入,配合shell命令,完成。我们知道可以使用tee 来将输入内容写入文件中。那么我们的命令可以是 :w !sudo tee % > /dev/null, 我们使用:w 来指定当前缓冲区的内容作为shell命令的输入。然后配合tee 来将内容写入到% 也就是当前文件。写入文件之后vim会检测到该文件已经被外部的程序修改了,本例中它被 tee 命令修改了,因此这个时候vim会提示我们文件已经被外部程序修改,需要重新载入文件还是使用当前缓冲区的内容。因为这里我们是将缓冲区内容直接覆盖到文件里面,二者的内容是一样的,使用哪个都行。由于neovim中该操作可能有问题,会报错,这里就不演示了,使用vim的小伙伴可以试试这个方法。后续我们可以使用扩展插件来解决这个问题。
2022年05月18日
11 阅读
0 评论
0 点赞
2022-05-11
vim 从嫌弃到依赖(11)——标签页操作
各位小伙伴们,你们好,我又更新了!之前介绍了vim关于多窗口的操作,vim中多窗口是将多个窗口在一个屏幕中显示,这似乎与我们常见的ide有点不一样,一般的ide都是新开一个窗口之后在新的标签页中显示,通过不同的标签页对应不同的文件。我们的浏览器就是一个典型的例子。而vim似乎不是这样的,vim管理文件采用的是缓冲区列表的方式,一个缓冲区对应一个显示窗口,而多个窗口可以显示在一个屏幕上。而vim中的标签页更像是一个容器,用来容纳这么些窗口。它更像是一个虚拟桌面,不管在功能上还是使用习惯上都像是虚拟桌面。(虚拟桌面可是个摸鱼的好东西,不过现在有更高级的摸鱼方法就是了。 有朝一日我一定要尝试用vim来摸鱼)除了使用它来摸鱼,我们再来想象这么一个场景:我们在做一个项目,已经打开了需要的代码文件,并且将它们经过了精心的布局,但是这个时候来了新的任务(以前的老项目出bug了,wtf!),我们不想在精心布置的窗口中插入这么一个第三者,总归心里有点别扭。这个时候我们新开一个标签页,在这个标签页里打开原来项目相关的文件。当我们修复完这个bug之后,直接切回到原来的标签页。之前的布局仍在原地等待着你(这么一个对你不离不弃的编辑器,多么令人感动)。我知道,看了我这么长的vim教程,很多小伙伴已经头晕脑胀了,甚至有的可能觉得最近介绍的东西,使用插件能更好的完成类似的操作,这些操作方式已经过时了。但是vim它提供了原生的操作,总有它的道理。打起精神来吧。标签页可以使用命令:tabedit {filename} 打开一个新的标签页,如果不加文件名则打开一个空的标签页。我们也可以使用tabnew 命令,参数与效果完全相同。如果当前标签页中包括多个窗口,那么可以使用<Ctrl+w>T 将当前缓冲区移动到新的标签页中。关闭标签可以使用tabc[lose] 或者使用tabo[nly] 来关闭标签页,前者是关闭当前标签页,后者是关闭所有,只保留当前激活的标签页。切换标签页在普通模式下使用gt 切换到下一个标签页,使用gT 切换到上一个标签页,也可以在命令模式中使用:tabn[ext] 和 tabp[revious] 来达到同样的效果。另外tabnext 和gt 前面都是支持添加数字编号的。这样我们可以方便的跳转到第几个标签页,这个编号是从1开始的。最后再介绍一个tabmove {n} 命令,它可以用来移动当前标签页到指定位置,后面加数字表示移动到第几个标签的位置,不加数字默认移动到结尾位置。当然如果你使用的是图形版的vim或者终端支持鼠标操作,也可以使用拖拽的方式完成这一工作。最后总结关于标签的操作,基本就这么多了。其实真要说起来,这些操作比较繁琐,记起来也麻烦,vim自带的标签功能相对比较简陋,后面我会介绍对应的插件对其进行扩充,本来我想跳过这部分的内容,毕竟有更好的插件和更好的操作方式。但是它作为vim提供的一大功能,使用频率也算比较大,想想还是说一下比较好吧。最后总结一下提到的一些命令吧::tabedit {filename} : 新建标签页,并在标签页中打开对应文件tabnew: 与tabedit 完全相同<Ctrl+w>T: 如果当前标签中有多个子窗口,它会将当前活动子窗口放到新的标签页中tabc[lose]: 关闭当前标签页tabo[nly]: 关闭除当前激活标签页的所有gt 或 :tabn[ext]: 切换到下一个标签页gT 或 tabp[revious]: 切换到上一个标签页tabmove {n}: 移动当前标签页
2022年05月11日
7 阅读
0 评论
1 点赞
2022-05-07
vim 从嫌弃到依赖(10)——缓冲区列表
之前的一系列文章主要介绍了vim文本相关的操作,并且也介绍了vim的几种模式。通过前面的内容,相信各位小伙伴们已经对vim有了一个基本的了解,同时也能够使用vim快速编辑文本,从这篇开始,我们将要介绍vim针对多个文件的操作,例如如何在多个文件中查找、跳转等等方式方法。让我们先从vim如何管理打开的多个文件开始吧缓冲区列表简介有过编程经验的小伙伴应该知道,将文件从磁盘读取到内存中时,都会事先分配一块内存缓冲区用来保存读取到的文件内容,vim同样是这么干的。vim在读取文件时会通过内存映射的方式,将磁盘中的内容映射到一块内存的缓冲中。vim可以打开多个文件,每个文件独立的占有一个缓冲区。为了管理这些打开的文件,vim中有了缓冲区列表的概念,同时也提供了一些配套的命令来操作缓冲区列表。假设现在在某个目录中有多个文件,我们使用vim同时打开,例如使用vim init.lua test.py。我们发现vim默认只展示一个文件中的内容,但是它打开了两个文件,现在有两个以文件名命名的缓冲区。通过命令:ls 查看当前打开的缓冲区。:ls 命令显示的内容每一行代表一个缓冲区的信息。它显示的信息如下::ls 1 %a ".\test.py" line 1 2 ".\init.lua" line 0第一列的数字代表缓冲区的编号,该编号由vim随机指定,第二列的%a 代表缓冲区为激活的缓冲区(active)当前窗口显示的内容为激活缓冲区的内容。第三列则是缓冲区的名称,一般vim会将文件名作为缓冲区的名称我们可以使用:bnext 按:ls 的显示顺序,显示下一个缓冲区,:bprev 显示上一个缓冲区。:blast 显示最后一个缓冲区,:bfirst显示第一个缓冲区。在切换过缓冲区之后再次执行:ls 之后发现此时显示的内容已有一些变化。现在显示的内容如下::ls 1 #h ".\test.py" line 1 2 %a ".\init.lua" line 1此时我们发现除了%a 代表当前处于激活状态的缓冲区外,另外一个缓冲区的前面多了个#h ,# 代表上一次处于激活状态的缓冲区,我们可以使用<ctrl + ^> 来切换到上次处于激活状态的缓冲区。而h 则代表隐藏缓冲区,当一个缓冲区由激活状态变为非激活状态的时候,vim会将其标记为隐藏缓冲区。除了按照顺序显示缓冲区,还可以通过缓冲区名称或者序号来指定显示某个缓冲区。例如使用:buffer 1 来显示编号为1的缓冲区。还可以更直观的使用buffer {bufname} 来显示指定缓冲区,其中{bufname} 代表的是缓冲区的名称,例如:buffer init.lua看到这里,各位小伙伴肯定会觉得不管使用:bnext 之类的命令切换还是使用:buffer 来切换缓冲区,都需要输入这么长的命令,显得既繁琐又低效,那么有没有什么办法来解决这个问题呢?答案是通过快捷键映射。后面介绍我自己的配置时会介绍如何将其映射到快捷键上如果要删除某个缓冲区可以使用:bdelete {bufname}。该命令支持前面几篇文章中提到的范围操作,即:nstart, nend bdelete 来删除编号nstart 到 nend 的所有缓冲区。缓冲区缓冲区编号是vim自己分配的,要通过编号删除得执行:ls命令,并且有时候删除了后续可能还要再次打开,再退一步说,如果暂时不想用它,vim也只显示后面打开的缓冲区,我们使用这个场景很少,除非有充足的理由,否则不会去删除它。缓冲区列表参数在实际开发项目的时候,我们会打开很多文件,如果仅仅使用上述介绍的命令会发现在管理上有诸多不便。例如项目中有ui文件、有python代码、也有c代码、甚至还有java代码,我现在要找一个名为showUserName 的函数,而且我很清楚我要的ui中的内容,但是在python、c或者java中都有类似的函数名,采用全局搜索肯定都搜出来了,但是我只想在ui文件中搜索。这就涉及到项目文件的模块化。使用上述命令肯定无法满足模块化的要求。这个工作可以使用列表参数来完成。假设现在目录有3个python 文件,5个cpp 文件,还有2个txt 文件,我们按照文件类型进行分组打开,先打开cpp 文件vim *.cpp使用 :args 显示参数列表。它输出的内容如下:[a.cpp] b.cpp c.cpp d.cpp e.cpp该列表记录了通过命令行另vim打开的所有文件缓冲区。其中使用[] 包裹起来的是当前处于激活状态也就是当前窗口显示的的缓冲。注意请不要被这个名字迷惑了,它并不是传递给vim的参数,而是作为参数传递给vim的文件的列表。也就是这条命令所打开的文件的列表。本质上仍然是一个缓冲区列表除了使用:args查看参数列表,也可以在:args 命令后添加缓冲区名称,例如:args init.lua 这样就将一个新的文件纳入之前的缓冲区列表中进行管理。后续可以将需要统一管理的缓冲区使用该命令添加进来,除了使用详细的文件名一个个添加之外,vim也支持使用通配符来进行匹配。甚至也可以在后面添加shell命令,以shell命令的输出作为缓冲区列表的参数,添加到参数列表,它的形式为:args `cmd`上述事例中,我们通过args 来将ls 输出的结果作为参数列表。再通过:ls 命令查看一下当前缓冲区列表,发现之前打开的仍然存在,只是我们将test.py 和 init.lua 这两个文件形成一组作为缓冲区的参数列表。当我们指定好了一组缓冲区列表参数之后,可以使用:next 、 :prev 、first、last 在这组缓冲区列表中进行切换。:args 命令本身也支持使用通配符来将所有匹配的文件名设置为缓冲区列表参数,例如:args *.py 将当前目录中所有py文件加入,或者使用:args **/*.py 来将当前目录下所有子目录中的py文件加入。一般来说使用shell命令或者使用通配符的方式居多,但是也有直接使用文件名的情况出现后面我们可以根据参数列表,对列表中所有的缓冲区进行统一的修改或者在这些缓冲区中进行跳转之类的操作,当然这些等我们介绍到了对应的基础知识后再进行演示。vim退出好像现在才讲到退出操作已经有点晚了,很多用上vim的小伙伴肯定也搜到如何退出了。不知道怎么退出的,应该已经退坑了。但是我在这里并不介绍使用何种命令来退出。而是介绍vim如何处理未同步到磁盘上的缓冲区的。我们随便打开多个文件,在任意一个或者多个缓冲区中执行o 或者其他能另其修改的命令。然后执行切换缓冲区的命令,例如:bnext 之类的,切换之后再次执行:ls 1 #h + ".\init.lua" line 2 2 %a ".\test.py" line 1我们发现在之前的基础之上,多了一个 + 它代表着这个缓冲区上的修改并未同步到磁盘文件中。此时如果执行:q 进行退出的话,会提示当前有缓冲区未同步到文件中,并且跳转到未同步的缓冲区。我们可以执行:w 来写入将缓冲区内容磁盘,也可以使用:q! 来忽略该缓冲区的修改,或者使用:edit!来强行的从磁盘读取内容并覆盖本次修改。这个时候vim将会切换到下一个未保存的缓冲区。如果嫌每次都这样比较麻烦,可以执行:qall! 忽略所有未修改的缓冲区并退出,或者使用:wall 来写入所有修改。总结本文到此就结束了,最后再来总结一下该文中使用到的命令和快捷键:bnext: 切换到缓冲区列表中的下一个缓冲区bprev: 切换到缓冲区列表中的下一个缓冲区blast: 切换到缓冲区列表中的最后一个缓冲区bfirst: 切换到缓冲区列表中的第一个缓冲区<Ctrl+^>: 在上一个被激活的缓冲区和当前被激活的缓冲区之间进行轮换args: 显示当前缓冲区列表参数。后面也可以跟上文件名、shell命令和通配符,设置对应的缓冲区列表参数next: 切换到缓冲区列表参数中的下一个缓冲区prev: 切换到缓冲区列表参数中的上一个缓冲区last: 切换到缓冲区列表参数中的最后一个缓冲区first: 切换到缓冲区列表参数中的第一个缓冲区
2022年05月07日
15 阅读
0 评论
1 点赞
2022-05-05
vim 从嫌弃到依赖(9)——命令模式进阶
上一篇文章更新还是在51前,最近发生了很多事情了,全国各地的疫情又有蔓延的趋势,北京朝阳区都已经开始实施居家办公。各位小伙伴请注意安全,安全平安的度过这个疫情。废话不多说了,接着上次的内容往下写。在上一个篇章中,我们介绍了命令模式的使用,也通过一些例子理解了在需要大范围操作文本或者进行光标跳转的情况下,相比于使用普通模式中的operator + motion 来说,使用范围加命令的方式更快速而且也更方便。同时也以copy 和 move 操作,介绍了操作文本命令的一搬用法。接下来就要继续往前走,介绍命令模式的其他用法了。命令行模式下使用普通模式的命令当初在第一次介绍. 命令的时候相信各位小伙伴应该有一个遗憾,怎么没有介绍.命令类似数字 + . 以达到重复执行目的的操作呢。如果有这么一个操作那岂不是如虎添翼。甚至可能有小伙伴自己亲自去尝试过,发现失败了。vim并没有提供类似的操作。那么要完成这件任务该如何来操作呢,之前的例子只有3行,每次使用. 之后使用j 来移动然后再使用. 也没几次,这个成本是可以接受的,但是如果是将文件中所有代码行的尾部都加分号,而且这个文件有上百行甚至上千行代码呢。之前针对这个例子给出了不同的解决方案,在学习. 命令的时候,是使用. 命令,在学习可视模式的时候使用处理列的可视模式。现在再介绍一种新的方式,通过在命令行模式中使用normal 关键字来告诉vim,我们将要使用普通模式的命令。它使用的方式为:range + normal + operator ,它支持范围操作,表示我们将要针对某个范围来执行普通模式的操作针对这个例子,首先要构造一个可以使用.命令的操作,即我们在首行使用A; 在行尾添加分号,接着配合命令模式的范围,加上2,$normal. 表示我们将要从第二行到尾行来执行. 命令这个在使用. 的时候,我们相当于在重复执行A; 的普通模式的命令,那么是不是可以做这样的猜想,使用:normal 也可以执行 A; 这样的命令做到同时切换输入模式并且自动输入字符,而不仅仅局限于执行operator呢?我们可以将上述修改使用2u回退,然后针对这个猜想做验证,输入:%moral A; 我们发现它确实成功完成了这样的操作。也就是说normal后是可以跟一些改变当前模式的命令并且可以指定输入的内容的。这样我们在快速删除一个文件的所有内容上,又有一种新办法了:$normal dd 但是相比起 :%d 来说要输入的字符更多罢了。他们的区别相信看到现在的小伙伴应该很熟悉了。这里就不再解释了,感兴趣的小伙伴也可以在评论区给出自己的答案。重复上次的ex命令在普通模式下. 可以重复上一次的修改,但是某些ex命令并没有对其进行修改,如果我想重复通过. 来重复上次的ex命令则无能为力了。而且通过实验也可以发现,它也无法重复由ex命令造成的修改。可以使用@: 重复上一次的命令。如果执行过 @: 进行重复,那么可以使用@@ 再次执行上次重复的命令,例如在编写代码时经常会一到的一个问题就是将当前行代码下移一行,但是也不是所有的行都会这么干,那么就可以先使用 .m.+1将当前位置的代码移动到光标的下一行,然后移动光标,在下一个需要次操作的位置执行 @: ,后面就可以直接使用 @@ 来重复上一次的操作了。这里就不再针对它来做演示了。各位小伙伴可以自己来尝试一下自动补全ex命令在使用shell 命令的时候,使用tab 可以很方便的进行补全,而在使用命令模式的时候也有这个功能vim在使用tab时会自动检索之前输入的历史进行匹配。例如,使用 :%n<tab>。它会匹配到一堆符合要求的命令。多次按下 <tab> 键则会依次按从上到下的顺序进行匹配。也可以使用 <Ctrl n> 和 <Ctrl p> 跳转到下一次匹配和上一次匹配。同样的也可以使用 <Shift Tab> 来跳转到上一次匹配默认情况下,会按照上述例子中的样式来展示匹配项,但是你也可以自定义匹配项,使用wildmode 来修改补全行为。但是需要事先打开 wildmenu 选项。可以使用 :h wildmode 和 :h wildmenu 来查看对应的帮助文档。这里我给出我习惯使用的配置vim.o.wildmenu = true vim.o.wildmode="full"set wildmenu set wildmode=full当然你不进行这样的配置也行,neovim 模式的补全模式就是这种回溯命令历史在 shell 中,可以使用上下键直接输入上次输入的命令或者在 bash_history 中记录了之前执行过的命令,vim也有同样的设计按下 : 进入到命令模式之后,可以使用方向键向上或者向下查找历史命令。除了使用 方向键以外,还可以使用 <Ctrl p> 和 <Ctrl n> 来遍历,但是使用方向键有一个好处是他们可以针对之前已经输入的内容对匹配的内容进行过滤。坏处在于,手指的移动幅度大,我们可以使用映射的方式将<Ctrl p> 和 <Ctrl n> 进行映射。这里我们仍然等到讲述快捷键映射的时候给出代码运行shell 命令在vim的命令模式中也可以执行shell命令。只需要在shell命令前面加上 ! 即可,例如执行 :!ls 将会执行ls 这个命令在vim的命令模式中,% 代表的是当前文件名,在运行某些可以传入文件名作为参数的命令时,可以使用它,例如我要执行当前的Python代码时可以使用 :!python %我们也可以将vim命令模式中的范围配合shell命令使用,这个时候范围中包含的内容将会作为shell命令的输入, 例如现在有这么一个文件,记录了一个文件列表,现在我想要按照文件名排序files: a.txt ccc.txt b.txt d.txt z.txt t.txt可以配合sort 使用 :2,$!sort,由于第一行是表头的文字不进行排序,所这里从第2行开始参与排序使用 write 和read 命令重定向vim缓冲区内容在vim配合shell命令使用的时候有时候shell会产生大量是输入或者需要一定的输出,那么就可以使用 write 和 read 来配合shell使用。read:vim从shell产生的输出中读取内容写入缓冲区write: vim将缓冲区的内容写入到shell中,作为shell的输入例如某个文件中有大量的Python代码,但是我只想执行部分,那么可以配合write使用,例如3,5write !python 执行文件中3-5行的Python代码,或者配合可视模式,执行选中的代码再比如,我现在需要获取当前目录下有多少个文件和目录,并且按照文件名顺序排列,就可以使用 :read !ls|sort。甚至配合键绑定,完成ide那种一件自动编译运行的效果。例如vim.api.nvim_set_keymap('n', '<F5>', ':write | !python %<CR>', {noremap = true, silent = true})配合文件类型识别可以做到一键执行其他类型的代码,将vim 打造成IDE不是梦想除了手工填写范围配合shell命令之外,vim提供了一种简便的方式来完成这一工作,可以使用 !{motion} 来快速形成范围,后面只需要输入命令即可,针对前面排序文件的例子,假设光标在文件的第二行,可以使用在普通模式下输入!G 来快速选中整行,vim为我们在右下角填充了:.,$! 后面只需要写上sort 之后就可以了到此为止,我们已经通过介绍不同的模式,将vim编辑文本的功能大致给展示了一下,相信各位小伙伴看到这里已经了解到了vim在编辑文本的强大。但是这并不是vim的全部,后面将详细介绍如何通过vim来组织文件、项目工程等功能。请各位敬请期待
2022年05月05日
7 阅读
0 评论
1 点赞
2022-04-27
vim 从嫌弃到依赖(8)——使用命令模式编辑文本
通过前面的文章,我们已经介绍了vim的普通模式、插入模式、可视模式。接下来让我们接着介绍vim中另一个强大的模式——命令行模式命令模式简介命令模式可以说在vim中的使用频率不亚于普通模式,像我们平时使用 :w 将缓冲区的内容写入文件,使用 :q 退出vim,这些都是在命令行模式下执行命令。vim最早是由 ed 编辑器发展而来,中间经历过了 ed --> ex --> vi --> vim 的流程,vim继承了vi的模式区分以及ex的一些处理文本的命令,这也就是为什么有时候会将vim命令行模式中执行的命令叫做ex命令在普通模式下,按下: 会切换到命令行模式,这个时候vim会等待我们输入一个命令,最后以回车(\<CR>) 结束输入并执行在vim 中有许多自带的的命令,而且我们安装第三方插件的时候,插件也会提供一些使用的命令,这里我们主要还是战士如何在命令模式中操作文本。其他相关的命令在后面结合其他功能给出在命令行中的操作与在插入模式中类似,只是插入模式会将键盘输入写入缓冲区,而命令行模式则会将输入显示在命令行位置。二者的操作符也类似,例如可以适用 <Ctrl-w> 和 <Ctrl-u>来删除至上个单词的开头和行首。也可是使用 <Ctrl-v> 和 <Ctrl-k> 来输入键盘上找不到的字符。也可是使用方向键来移动光标,或者使用退格键删除命令。如果中途不想执行输入的命令,可以使用<Esc> 退回到普通模式。在普通模式下,我们需要使用 operator +motion 来操作指定范围的文本,这通常伴随着光标的移动。在命令行模式下,可以操作任意范围内的文本,这表示在某些情况下,使用命令相对于在普通模式下有着更高的效率我们可以在一个或者多个连续行上执行命令,例如print("hello world1") print("hello world2") print("hello world3") print("hello world4") print("hello world5") print("hello world6")假设光标在第一行的行首位置,我们输入 :print ,它会打印当前行。我们看到执行print 之后会打印光标所在行配合范围使用命令与普通模式下 operator 配合一个 motion 来指定操作的文本范围类似,ex命令也可以带有一个范围值来指定操作的范围。这里我们给出一个使用范围的格式格式command = {startpoint},{endpoint} + cmd其中 startpoint 表示开始位置,endpoint表示结束位置,他们中间用,隔开,后面紧跟着一个命令。如果不加范围,则表示操作的范围是光标所在行,例如 :print 表示打印光标所在行的文本如果只输入一个数字,vim会首先将光标移动到对应的行上,然后针对该行文本执行操作,例如如果输入 :2print 它会将光标移动到第二行,然后对第二行文本执行打印操作。使用数字代表对应行下面再看一个例子:print("hello world1") print("hello world2") print("hello world3") print("hello world4") print("hello world5") print("hello world6") print("hello world7")我们要删除第三到第5行范围内的文本,就可以输入 :3,5d, 其中d 代表 delete 是删除的命令通过上述例子发现,在使用命令模式的时候,不需要在意光标所在位置,如果我们采用普通模式的解法,就需要先使用 3gg 跳转到第三行,然后使用3dd 删除三行。或者在第三行使用V 进入可视模式,然后选中3行,接着使用d 删除选中。对比这么几种方式来看,使用命令模式更加的灵活使用特殊符号代表对应行除了使用数字来代表对应行号所在行外,还是使用一些特殊符号来表达一些特殊含义,例如我们可以使用 . 来代表当前光标所在行,所以针对上述操作,我们还有一个解法:使用3gg 跳转到第三行,然后使用 :.,5d 删除当前行到第5行的内容除了使用. 来作为相对行号以外,命令模式中还有其他常用符号,这里列举一些供大家参考:.: 当前行$: 文件末尾0: 虚拟行,位于文件第一行的上方1: 文件第一行'm: 包含标记m的行<: 高亮选区的起始行>: 高亮选区的结尾行%: 整个文件,相当于 :1,$介绍了这些操作符之后,如果我们需要删除整个文件,那么有这么几种方法方法1:普通模式下,使用 0 跳转到第一行, 然后使用dG 第一行到最后一行的内容方法2: 命令模式下,使用 :1,$d 删除第一行到最后一行的内容方法3: 命令模式下,使用 :%d 删除所有使用位置偏移量来微调操作范围在 {startpoint}, {endpoint} 中二者均为绝对地址,除了使用绝对地址,我们也可以使用绝对地址+偏移地址的方式来定义操作范围。可以在绝对地址上使用 + 或者 - 来定义如何进行偏移,例如 $-3 会定位到导数第4行。假设我有超过1000行的文本,我想保留前3行和后3行,使用命令的时候可以使用:4,$-3d将可视模式的选区作为操作范围手动指定范围的时候,有时候需要我们去手工数开始行号和结尾行号,数数也算是一个比较累的体力活。除了使用之前的方式外,还可以使用可视模式。将可视模式的选区作为操作区。我们还是来看上面的删除第一行到第5行的例子,配合可视模式就可以这么做:先使用V 进入可视模式,然后使用 2j 选中两行,然后输入:d 进行删除 我们发现在选中一个选区后,按下: ,在左下角会出现 <,> 的字样,根据前面的列表知道 他们代表的是被选中的高亮选区。其他操作文本的命令在上面的例子中,我们主要使用了 d 这个命令来删除文本,除了它还有其他一些处理文本的命令,每个类型的命令接收的参数都各有千秋,但是也很好理解,这里我以 t (拷贝粘贴) 和 m (移动)为例,希望可以做到抛砖引玉的作用,帮助大家理解其他一些常用的命令。使用t 命令t 命令代表拷贝和粘贴,可以理解为 CopyTo。它需要两个参数,一个范围代表拷贝哪个范围的文本,一个位置,代表要将拷贝的内容放置在哪个位置。它的形式如下::range + t + address第一个range 代表的是范围,要将哪个范围内的文本进行粘贴,第二个address 代表的是一个行号,要将粘贴的内容放置到哪个位置这里我们给出一个示例来说明如何使用今日完成工作情况 1. fixbug 1 2. fixbug2 3. fixbug3 4. fixbug4 明日计划 5. fixbug5 6. fixbug6 7. fixbug7假设有这么一个日报,但是我今日工作完成之后发现离下班还有点时间,为了获得内卷达人的称号,我决定先看看明天的 bug5但是又不想为此加班太多,只是简单的看看,然后在工作日报上进行汇报,也就是说我要将fixbug5 复制一份放到今天的任务中。我们可以使用 :7t5 来将第7行的内容复制到第5行下方当然也可以先使用 7gg 跳转到第7行,然后使用 yy 复制该行,接着使用 5gg 跳转到第5行,最后使用p 进行粘贴。对比这种方式使用命令更加简洁,它省略了几次光标跳转的过程。由此看来,在需要大范围操作或者跳转的时候,使用命令会更加简洁也会更加高效还是以这个日报为例,随着我不要命的卷,终于在今天把bug5给修复了,虽然拉着其他同事陪我加了“一会班”,但是我超额完成了任务,老板承诺的绩效和年终奖马上要到手了,想想就觉得心里美滋滋,我要把明天修复的bug5提前到今天。想到这里我使用 :7m5 完成这一操作之后,打卡下班,未来可期如果再卷点,我能把明天要修复的bug全都在今天修完了,所以我这个时候想在工作日报中把明日计划工作全部移动到今天来,假设当前光标处于 bug5的位置,我可以执行:.+2,$m.。至此我带着出任总经理,担任CEO,迎娶白富美,走向人生巅峰的美梦沉沉睡去。总结到此为止,这篇文章的内容就完了,最后给大家总结一下主要内容命令模式是vim中又一重要的模式,使用率不亚于普通模式命令可以配合数字或者其他符号使用,代表将要操作的文本范围主要以 t 和 m 命令介绍了操作文本命令的用法最后再给出一些命令和范围的总结供大家查阅文本操作命令命令简写用途:[range]delete [x]d删除指定范围内的行[到寄存器 x 中]:[range]yank [x]y复制指定范围的行[到寄存器 x 中]:[line]put [x]pu在指定行后粘贴寄存器 x 中的内容:[range]copy {address}t把指定范围内的行拷贝到 {address} 所指定的行之下:[range]move {address}m把指定范围内的行移动到 {address} 所指定的行之下:[range]joinj连接指定范围内的行:[range]normal {commands}narm对指定范围内的每一行执行普通模式命令 {commands}:[range]substitute/{pattern}/ {string}/[flags]s把指定范围内出现{pattern}的地方替换为{string}:[range]global/{pattern}/[cmd]g对指定范围内匹配{pattern}的所有行,在其上执行Ex 命令{cmd}有些命令暂时还不知道怎么用,不着急,后面说到对应部分,自然会提到的范围符号符号用途.当前行$文件末尾0虚拟行,位于文件第一行的上方1文件第一行'm包含标记m的行<高亮选区的起始行>高亮选区的结尾行%整个文件,相当于 :1,$
2022年04月27日
10 阅读
0 评论
1 点赞
2022-04-25
vim 从嫌弃到依赖(7)——可视模式
vim 的可视模式下可以选择一个区域,然后针对区域进行操作。可视模式有点类似于在其他编辑器上使用鼠标选中一块区域然后针对区域进行操作。vim中有3种可视模式,分别用来处理不同范围的文本:处理字符的可视模式处理行的可视模式处理列块的可视模式在普通的文本编辑器中,例如在写博客的时候会发现有些地方表述不太正确,这个时候一般会选择先用鼠标选择一句或者一段,然后按退格或者删除键删除所选内容。vim的可视模式也是相同的逻辑,先选区然后对选区进行操作。选区时可以使用之前介绍的motion 来移动光标进行选区,操作选区的时候可以使用 operator 进行。直接说可能有点抽象,下面看一个例子:我们将 there is one more line 改为 there is one line。在上述例子中,我们使用 v 进入可视模式,在处理字符的可视模式下会在左下方显示 VISUAL 字样表示进入了处理字符的可视模式。在该模式中使用e 选中一个单词,然后使用d 删除它我们发现在可视模式下操作的逻辑与在普通模式下的操作逻辑不太相同,可视模式下先使用motion 移动光标选中部分内容,然后调用operator 来对选中部分做操作。而普通模式下先调用 operator 声明需要进行的操作,再使用motion 传入要操作的文本范围。但是可视模式下的操作逻辑确与一般的文本编辑器类似,都是现选中一个部分,然后再针对这部分进行操作。选择模式在一般的编辑器中,选中一段文本后,输入任意字符会先删除选中部分然后再插入输入的字符,但是vim的可视模式并没有这么做。从上面的例子也可以看出来,vim的可视模式保持了普通模式中使用操作符操作区域的逻辑。但是vim也提供了类似于普通编辑器一样的体验,这个体验就是选择模式。在可视模式下使用 <Ctrl +g> 进入选择模式,下面是一个选择模式的例子在进入可视模式后,使用<Ctrl +g> 进入选择模式,此时左下角的字样已经变为 SELECT,表示此时进入了选择模式。在选择模式中,随便输入一个字符,它会删除选中然后输入对应的内容。相信能看到这里的小伙伴已经很熟练的使用vim进行文本操作了。这个模式主要是为了迎合那些想让 vim 像其他编辑器那样的用户。这种模式效率并不高,而且也不太推荐使用这种模式。可视模式的3种子模式可视模式下有3种处理不同情况的子模式,分别为:处理字符的可视模式、处理行的可视模式、处理列的可视模式处理字符的可视模式与普通的motion 配合使用,可以选中光标移动所经过的字符。可以在普通模式下按v 进入处理行的可视模式可以与行操作的motion 配合,一次选中一行,可以在普通模式下按 V 进入处理列的可视模式可以与一般的motion 配合,一次选中一列,行操作可以选中多列,而h l 则可以选中多列。3种模式下可以互相转化,按键与上面介绍的相同。例如从处理字符的选择模式切换到处理行的可以使用V ,从处理列的选择模式切换到处理行的,可以使用v。但是如果处在处理字符的可是模式下再次按下v 则会退回到普通模式,在其他模式下类似。重新选择选中区域如果选择到一半发现我们选择错了该怎么办呢?一种方式是退回到普通模式下,然后再重新进入选择模式。但是在这里要介绍一种新的方式——可以按 o 重新选择选区的活动段。选择模式下选区一段固定,另一端可以移动。通过多次按下o 来变更需要移动哪一段例如下面的例子示例上面叽里呱啦说了一堆,可能各位小伙伴都没怎么记住,下面给出一些例子,帮助大家来理解之前说到的一些内容示例1:缩进Python代码假设有这么一段Python代码def fib(n): a , b = 0, 1 while a < n: print(a) a , b = b, a + b fib(42)要将中间两行缩进两次,变为下面的代码def fib(n): a , b = 0, 1 while a < n: print(a) a , b = b, a + b fib(42)解法1: 可以在普通模式下,在对应位置使用 2>> 将两行缩进一次,然后使用 .命令再重复一次解法2:使用>j 缩进两行,然后使用 . 重复,效果与上面的解法1一样,这里就不演示了解法3:使用 V 选中一行,然后使用2> 缩进2次,移动到下一行后使用 .重复解法4:使用V 选中一行,然后使用j 再选中一行,接着使用2>> 将选中两行一次缩进两次 解法5:这里介绍一个在可视模式下的新命令——gv 它可以选中上次选中的区域。结合这个命令可以这么操作,先选择两行,再使用> 缩进一次,然后使用 gv 选中上次选中的两行,再次使用 >针对示例1,我给出了5种解法,有利用普通模式加. 命令的方式,也有利用现学的可视模式的解法。当然也有其他的解法,各位小伙伴有好的方式也可以在底下评论。上面不管哪种解法,大部分都使用了.命令,这里也可以看出. 在处理重复操作时候的威力。虽然它很好用,但是也需要注意:在基于字符的可视模式下 . 命令操作的字符数与上次修改中操作的字符数相等。例如world world1 world11 world111当我们在第一行使用 v 进入选择模式,然后使用e 选中一个单词删除它之后,再在下一行执行. 命令的时候,并没有删除一行,只删除了world这个单词针对示例1给出的几个解法,我们发现使用可视模式在效率上有时候还不如在普通模式下配合. 来使用,这么说是不是说可视模式就失去了它的价值呢?其实也不是,在平时处理文本的操作中,并不是每个任务都需要进行重复,在处理一次性操作的任务时,vim的可视模式在效率上于普通模式其实差距不大,而且有时候要修改的文本所在区域无法准确的通过一两个motion 表达出来,这种情况下可视模式就大大的派上用场了。下面几个列子就可以说明这点。示例2:处理列的可视模式的初步使用假设我们要将下列代码Print("hello world") Print("hello world") Print("hello world") Print("hello world") Print("hello world")变为print("hello world") print("hello world") print("hello world") print("hello world") print("hello world")可以使用 <Ctrl + v> 进入处理列的可视模式,然后选中所有的P,接着使用 u 将其变为小写示例3:添加注释假设现在有一些Python代码需要添加注释,即将下列代码print("hello world") print("hello world") print("hello world") print("hello world") print("hello world") print("hello world")变为#print("hello world") #print("hello world") #print("hello world") #print("hello world") #print("hello world") #print("hello world")可以使用 <Ctrl + v> 进入处理列的可视模式,然后选中所有的p,然后使用 I 在行首进入插入模式,接着输入 # 注释代码,最后使用 <Esc> 退回到普通模式,我们可以看到在插入时它只显示了一行的变化,但是最后回到普通模式后,针对第一行的变化作用到了所有选中行示例3:在每行代码后添加一个分号还是将之前介绍. 命令的那个例子来作为示例,但是这里提供一个使用列处理的可视模式的方式在下列代码的每一行行尾添加一个分号var foot = "foot" var ball = "ball" var football = foot + ball变为var foot = "foot"; var ball = "ball"; var football = foot + ball;现将光标移动到第一行的最后一列,然后使用<Ctrl v> 进入到处理列的可视模式中,然后移动光标到最后一行的行尾。接着使用A 进入插入模式,输入分号,最后使用<Esc> 回到普通模式。这个时候我们发现vim在被选中区域每一行的尾部都添加了一个分号在普通模式下 i I a A 都有自己的用途,而在处理列的可视模式下我们都只是在用 I 和 A ,而且他们的含义与在普通模式下有所不同,在处理列的可视模式中,A 表示在选择区的每个行尾进行同样的操作,而I 表示在选择区的行首进行同样的操作。至于a 和 i 这里则代表要处理的文本对象。到此我们介绍完了vim中又一个常用的模式,再下一篇中,将介绍vim的另一种常用的模式——命令模式。
2022年04月25日
6 阅读
0 评论
1 点赞
2022-04-21
vim 从嫌弃到依赖(6)——插入模式
插入模式是vim中主要用来处理输入的一种模式,在这种模式中,用户的输入的字符会显示在窗口中。该模式中的行为与在普通编辑器中输入类似。由于在该模式中输入的字符会被当做有效输入,因此该模式下涉及的到命令也少,内容也不多,这一篇文章差不多就能讲完进入插入模式的一些命令在前面几节我们在介绍一些例子的时候或多或少接触到了如何进入插入模式,特别是用的比较多的 i、c 等命令。而且还介绍了一些复合命令,有些复合命令同时也肩负着进入插入模式的职责。这里列出一些常用的进入插入模式的方法,也算是对之前的一些命令做一个总结。命令含义i在当前光标前进入插入模式I在行首进入插入模式a在当前光标后面进入插入模式A在行尾进入插入模式o在下一行进入插入模式O在上一行进入插入模式s删除当前光标所在字符并进入插入模式S删除光标所在行并进入模式c + motion删除指定范围的字符,并进入插入模式C删除光标所在位置至行尾的字符,并进入插入模式在插入模式中删除字符在插入模式中输入出错,我们一般会退出到普通模式下使用c或者d之类的指令进行删除操作,然后重新进入插入模式,但是有时候这种方式显的有些啰嗦。其实在插入模式中是可以进行删除操作的,例如如果要删除的字符刚好在光标前面,我们可以使用退格键删除它。另外vim提供了其他几种方式在插入模式中向前删除单词、行: 删除光标前一个词(与退格键相同): 删除光标前一个单词: 删除至行首插入-普通模式从插入模式返回到普通模式可以使用 \<Esc\> 键,或者使用 <C-[>, 但是在某些情况下我主要的经历还是集中在编写代码或者文档上面,之前也说过vim 作为编辑器应该要符合人的一般使用习惯,在文思如泉涌的时候退回到普通模式总有种割裂感,普通模式应该是我们在需要调整思路的时候回去最好。假设我在写文档或者写代码的时候光标已经到窗口的最后一行了,但是我想将光标定位到窗口中央,一般都会先退回到普通模式,然后使用前面介绍过的 zz来完成这一动作,最后再进入插入模式。针对这种情况vim 提供了一种新的模式 插入—普通模式,在插入模式中使用Ctrl + o 来进入该模式。该模式运行用户暂时回到普通模式,然后在执行一条普通模式的命令之后自动回到插入模式中。例如针对上面的例子,可以使用 \<Ctrl +o>zz 来刷新光标位置插入非常用字符在平时输入的时候,除了常用的英文单词或者汉字之类的字符还有一些非常用字符,例如unicode 图标或者ascii 字符,或者其他键盘无法直接打出的字符。vim 支持使用通过字符的二进制编码进行输入 {code}:按照字符的十进制编码输入,这里code只能输入单字节的字符u{code}: 按照字符的16进制编码输入,这里可以支持两个字节的字符输入,例如unicode例如可以使用该方式输入字符A,A在ascii表的十进制值是65,因此在插入模式下使用 <Ctrl v>65 然后回车即可这里再给出一个输入unicode字符的例子,例如我们输入一个安卓的小机器人,通过查询对应的unicode字码表,它的16进制值是 e70e,那么我们就可以输入<Ctrl v>ue70e除了输入字符表中的例子,也可以输入二合字符。可以使用 <C-k>{char1}{char2} 来输入二合字符,例如要输入分数 1/2可以使用<C-v>12 来进行。这个技巧也是 《vim实用技巧》 书中介绍的,可以在vim中使用 :h digraph-table 来查看二合字母表。平时写代码基本用不到这个,所以这里就一笔带过吧。替换模式vim 中的替换模式与改写模式类似。它会将光标所在字符替换为新输入的字符,按照 vim官方文档的说法,替换模式不会变更文本自身的长度,只会在现有长度上替换已有文本。只有在光标超出原有文本长度时才会表现出插入字符这一特性。而且在替换模式下没有删除的操作。在某些情况下替换可能会导致代码格式错乱,如果代码中某些位置存在制表符,而制表符的宽度会根据tabstop 的值不同,而显示不同,例如vim 默认的制表符占8个空格,如果我们使用R 进入替换模式,替换tab键的话,原来的tab键所有空白字符都会被替换,这样会导致文本长度发生变化。如果不希望长度变化,vim提供了一种被称之为虚拟替换模式的方式,可以使用 gR 进入,这样再替换制表符的话,制表符被替换为一个字符+ 多余的空格,源文本长度不变。使用普通的替换模式使用虚拟替换模式除了进入和退出替换模式,如果只是想替换一次,可以使用r{char} 和 gr{char} 暂时进入替换模式,替换一个字符后立即回到普通模式替换模式就我自己来说用的还是比较少的,除非我只需要替换个别字符导致的拼写错误。一般我更习惯删除整个单词,然后重新输入。至于虚拟替换模式解决tab 的问题,我更喜欢使用一些配置将tab 键改为空格,这里我们在配置文件中再添加几行-- nvim lua 配置 vim.o.softtabstop = 4 vim.o.shiftwidth = 4 vim.o.expandtab = true# vimscript set softtabstop=4 set shiftwidth = 4 set expandtab = true这几行会将tab替换为4个空格,并且在一些代码中,如果加入了自动缩进的属性,在输入下一行的时候它会自动以4个空格进行缩进到这里,插入模式下的一些内容都介绍完了,插入模式主要用来做文本输入,与在其他编辑器中输入文本相比并没有太大的区别,所以内容比较少,只需要一篇就结束了。请各位多多支持,订阅专栏,关注作者。方便接收更新推送和日后系统性的回顾,谢谢大家
2022年04月21日
8 阅读
0 评论
1 点赞
2022-04-19
vim 从嫌弃到依赖(5)——普通模式的一些操作
通过前面几章内容的铺垫,基本已经介绍完了普通模式的大部分内容,按照进度下面会依次介绍插入模式、命令模式、选择模式的一些操作。根据不同模式提供功能的多少和使用频率,篇幅会有长有短。本来这篇文章应该介绍插入模式的。但是我在整理最近写的内容的时候发现我忘记了一些不太常用但是很好用的一些小技巧,所以这篇文章我们还是停留在普通模式下。快速翻阅文本跳转光标的操作,之前介绍过 h j k l w等操作,但是在阅读代码的时候,仅仅根据这几个操作,效率着实有点低,即使使用类似 数字 + j/k 的方式来进行行间跳转,效率也一般。这里再介绍几个操作ctrl + f: 向下翻页ctrl + b: 向上翻页这里没有什么具体的例子,各位小伙伴只需要找到一个大一点的文件试试就能看到效果 除了使用这种翻到下一页或者上一页的操作之前,还可以相对于光标滚屏zt: 将光标所在行移动到窗口顶端zb: 将光标所在行移动到窗口底端zz: 将光标所在行移动到窗口中央这个提供两个问题:为什么没有将他们放到前面跟 h j k l 这类的操作一块讲呢,当然是因为我忘记了啊。。。。这个理由虽然很重要,但是并不是主要理由。大家可以先猜猜。既然这个操作能大幅度提高我们阅读代码的效率,那为什么使用频率还会这么低呢有兴趣的小伙伴可以先不看后面的解答,自己操作一下,特别是在认真阅读代码的时候。可能就会有跟我下面说的一样的体验好了,现在公布我的答案:针对问题一,我的答案是,这几个操作并不属于motion 那一类,小伙伴们在试验的时候可以仔细观察一下光标,光标相对于窗口的位置其实并没有发生变化。大家在阅读代码的时候使用它们会不会觉得跳转太多了,每次跳转都感觉跟前面读过的衔接不上呢。体验非常不好,还不如我一直使用 jjjjjjjjj 甚至 10j 之类的操作。现在我采取折中的办法,就是翻页的快捷键我用,但是我将其映射为了 10j (如何映射快捷键以及如何定制自己的vim在后面说)撤销撤销在普通模式下使用 u,反撤销使用 Ctrl+rvim的撤销是撤销上次修改,结合之前介绍的. 命令的部分,我们可以知道上次修改指的是从进入插入模式那一刻起到退回到普通模式为止,进行的一系列的修改。根据这个特征,我们可以很方便的定义撤销哪些内容。例如在写这篇文章的时候我进入插入模式进行编写。然后在需要构思的地方退回到普通模式,想到了一些再次进入插入模式编辑,一旦发现有问题就可以在普通模式下撤销上次的修改。例如下面的例子:我们先使用 cw 替换一个单词,然后删除一行。使用u 恢复上一次的修改,也就是恢复删除的一行使用 ctrl + r 执行反撤销,即再次删除上次恢复的一行u 和 ctrl+u 是操作符,它们符合之前介绍的 operat = 数字 + operator的公式,因此如果想要恢复到最开始的状态,可以使用 2u普通模式下对数字文本进行递增递减操作假设我们这么一段代码var foo = 5 + i;现在希望改为var foo = 10 + i;我们当然可以使用cw 来删除5,然后在插入模式下写入10。但是这里要介绍一个新的方法——使用 Ctrl + a 来在数字文本上进行递增操作,它也是一个操作符。符合之前的公式。这里假设光标在 5 的位置,然后执行 5 Ctrl+a 来实现将5这个数字文本递增5个的操作递减操作使用 Ctrl x 。下面请各位试试这么几种情况:如果光标不在数字位置,执行 Ctrl a 会发生什么呢?假设代码中有不止一个位置有数字,光标也不在某个具体数字上,执行Ctrl + a 又会发生什么呢?当前行没有数字,在后面几行有数字,执行Ctrl a 会发生什么呢?下面公布答案如果光标不在数字所在位置,该命令会在本行往后查找第一个出现数字的地方,并将光标跳转到该处,然后执行加1的操作。花了这么多篇幅总算将普通模式下的一些操作说完了,后面将会进入按照顺序分别讲述,插入模式、选择模式、命令模式。请感兴趣的小伙伴关注一下本专栏,有想要了解的内容也欢迎留言,等我按计划更新完了我想写的内容之后会考虑安排上的,在此谢谢小伙伴的捧场
2022年04月19日
7 阅读
0 评论
1 点赞
2022-04-17
vim 从嫌弃到依赖(4)—— .命令
通过之前几篇文章的介绍,如果各位小伙伴能够勤加练习,并在日常工作上经常使用,那么相信那些内容已经会对工作效率的提升产生好的影响。但是如果那些就是vim的全部的话,我们也就没那么大的必要花这么大的精力来学习如何使用它,而且它也不会在程序员中口口相传,并且令很多程序员对它如此着迷。接下来让我们更加深入到vim中,去学习更多更好的,可以进一步提升效率的技巧Don’t Repeat Yourself. Let vim repeat it for you不要进行重复的操作,让vim替你自动完成这些重复的操作。vim之所以好用,效率高。就是它对重复操作进行了大量的优化,并且提供了一些方式方法能让你不必做重复功。而且尽量让这些方法简单易用。最简单的就是使用. 来重复上次修改(确实是够简单的)废话不多说,还是以例子来说明假设我有这样一段Python代码if user == "vim": print("vim is best!") else: print("vim is not best")我需要将第2行和第3行进行缩进,可以这么做,先使用j 移动光标到第二行,然后使用 >> 缩进代码,接着使用 2j 跳转光标到第四行,然后使用 . 重复上一次修改配合搜索命令可以完成对文本的快速修改,但是我们现在还没介绍到搜索相关操作,所以先按下不表如何定义上次修改不同的编辑器对上次修改的定义不同,有的可能是词、句子、段甚至有的可能按照输入时间来算,一段时间内的输入算作上次修改,而vim可以自己定义上次修改范围是多少。vim一般将从进入插入模式开始,到从插入模式退出这段时间内做的修改做为上次修改,或者在普通模式下将我们使用一次operat = operator + motion 公式作为一次修改,例如我们有这么一段话this is no more one line this is no more one line我们将光标移动到 第一个n 处。然后使用d2w 删除两个单词,然后再下一行再次使用. 发现它执行与上一行一样的操作在进入插入模式时,连同进入插入模式的操作一起与在插入模式下输入的内容一同被算作上次修改,例如this is only one line this is only one line改为this is no more one line this is no more one line我们可以先将光标移动到 only 的首位,然后使用 cw 进入插入模式,输入 no more 退出输入模式,接着使用j 移动到下一行,再使用 2b 移动到第二行同样的位置,最后使用 . 来重复上一次修改仅限于进入插入模式的一次操作,而之前进行的移动光标之类的操作就不再统计为一次修改。例如有这么一段代码var foot = "foot" var ball = "ball" var football = foot + bar我们要在每行的后面加上一个分号。方案一:可以先使用 $移动光标到行尾,然后使用 a 插入模式,接着添加一个分号,在下一行需要先使用$ 移动光标到行尾,然后使用. 直接使用,就会变成这样针对这种情况只有事先手动的调整光标位置,然后使用点命令。这里就不演示了针对这个例子,我们有更高效的方法,可以使用复合命令。使用A 可以直接从行尾进入插入模式方案二:使用 A 在行尾进入插入模式,节省后续移动光标的步骤通过这个例子,我们看到了使用复合命令加上. 可以极大的简化重复操作,提高效率。在这里再给出一些类似的复合命令给各位小伙伴参考复合命令等效长命令含义A$a在行尾进入插入模式I^i在行首进入插入模式oA\<CR>在下一行进入插入模式Oko(k$a\<CR>)在上一行进入插入模式S^c$删除当前行并进入插入模式Cc$删除当前光标位置到行尾的内容并进入插入模式scl删除光标后的一个字符并进入插入模式在《vim实用技巧》这本书中,作者介绍了一个实用vim的经典范式——一个键移动、另一个键操作。例如上述实用. 命令的操作中,使用j 来移动行,然后使用. 来执行操作。后续将有许多操作使用该范式。最后还是做一个总结:本篇讲述了vim中比较强大的一个命令——. 命令,它能重复上次修改。但是需要注意以下几点:上次修改是从进入插入模式开始,到回到普通模式为止这段时间内做的修改,或者在普通模式下使用一条命令进行的修改. 命令并不关心上次修改的位置,只会简单的重复上次修改。所以在使用前尽量考虑该使用哪些命令能最大限度的让. 重复更多操作。使用复合命令不光能减少输入字符数,配合. 命令将产生强大的效果
2022年04月17日
7 阅读
0 评论
0 点赞
1
2
3