整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Vim 常用操作命令整理

im是类unix系统里最常用的编辑器之一,有很多常用的操作命令,如果能熟练使用,一定会提高自己的输入速度,接下来整理了常用的命令。

打开关闭

  • vim xxx,vim +num xxx 命令行打开文件
    vim + filename 启动跳到文件结尾
    vim +143 filename 打开跳到143行 调试代码有用
    vim +/search-term filename 跳到第一个匹配
    vim +/search-term filename 跳到最后一个匹配
    vim -t tag
    vim —cmd command filename 加载文件前执行命令
    vim -c “:50” filename 加载文件后执行命令
    :e xxx vim中打开文件
    :w[rite],:up[date],:w!,up!,:wall保存文件
    : x,:q,:qa,:q!,退出文件
    gf 普通模式下打开文件名为光标处文字的文件
    Ctrl+W f 新窗口打开匹配的文件
    Ctrl+W fg 新tab页打开匹配的文件

代码相关

  • <,>对代码进行缩进
    <<,>>用于调整源代码缩进格式
    = 用户自动格式化代码缩进,gg=G 即为全文格式化
    zf,zo,zc,za,zR,zM对代码进行折叠打开折叠
    Ctrl+],Ctrl+T查找函数的定义和返回
    大写K,看光标所指标识符的man帮助

移动光标

  • h,j,k,l ←↓↑→ 移动光标,相当于四个方向键
    w,b,e,ge 以单词的方式移动,可以nw,nb,ne,nge的方式移动n个单词的距离
    W,B,E,gE会以连续字符串的方式移动
    0,^,g_,移动到行首,行尾以及后面第n行的行尾
    gg,G,nG,ngg 移动到文件头和文件尾,以及移动到文件的第n行,‘可以回到上一次的地方
    H,M,L n%定位光标到当前屏幕的某个地方
    {,},[[,]],(,) 段落,区块,语句导航
    z回车,z-,zz.当前行置顶,置底,置中
    Ctrl+G显示当前位置信息
    Ctrl+F,Ctrl+B,Ctrl+U,Ctrl+D,Ctrl+E,Ctrl+Y,向前后滚动一屏,半屏,一行
    Ctrl+I,Ctrl+O 光标移到下一次和上一次的地方,Ctrl+I 和Tab功能一样
    ‘,”,[,]为跳转前的位置,最后编辑的光标位置,最后修改的开始位置,最后修改的结束位置
    Ctrl+^ 在两个文件之间轮换
    ‘“,’.,`.上一次光标的地方,上一次修改的地方

编辑

  • i,a,o,I,A,O分别进入插入模式
    o 在当前光标所在行下方插入一行,O在当前光标所在行上方插入一行
    J 删除换行符,合并两行
    Ctrl-R 重做
    u,nu撤销上一次更改,撤销n次更改
    U 撤销整行的更改
    Ctrl+R 重做更改
    Ctrl+L 重新加载屏幕内容
    y,d,p 表示拷贝,删除,粘贴,配置位置描述使用 yw,dw,y0,d0,y,yfa,dfa,yy,dd,D,dG,dgg等,前面可以加数字,表示重复如,3dd,3yy等,也可以加范围,如4,8yy
    %y+.y+,N,My+ 拷贝指定的数据
    :[range] g[lobal[!]] /{pattern}/ [cmd]
    :[range] v[global[!]] /{pattern}/ [cmd]
    n,p,next,previous,Ctrl+^在编辑的文件中切换
    :ls 查看打开的文件
    :e #n 打开标号为ls结果中的文件
    :changes 查看文件变化
    ga查看ASCII,十进制,十六进制

查找

  • /pattern-回车 在文件内向后查找pattern的匹配,n重复,N回退,n前面可以带数字
    ?pattern-回车 在文件内向前查找pattern的匹配,n重复,N回退,n前面可以带数字
    f{char}/t{char} 在行内查找下一指定字符, ;重复, ,回退
    F{char}/T{char} 在行内查找上一指定字符, ;重复, ,回退
    *,#高亮所有匹配光标所在单词,相当于输入了/word,如果想单独匹配单词/\<word\>,则需要g*,g# ,gd提留在非注释段的第一个匹配
    \<,\>表示匹配单词的开头和结尾
    .,^,$在查找的过程中作为正则策略,如果需要完全匹配需要转义
    % 查找匹配的括号() [] {}

替换

  • . 重复上次的修改(一定要是修改) 比如说上次删除一个字符,点就是删除一个字符的意思;如果上次是删除一行,点就是删除一行的意思了。
    >G 当前行缩进一个单位(Tab)
    :[range]s[ubstitute]/{pattern}/{string}/[flags] 将范围内的from 改为to,替换当前行
    :[range]%s[ubstitute]/{pattern}/{string}/[flags] 将范围内的from 改为to,替换所有行
    范围可以指定为m,n的数字形式,当个的数字表示特定的行,.表示当前行,如果字符串中本身包含/,则可用+,=替换原来的/
    :[range]s[ubstitute]/{pattern}/{string}/[flags] [count]

外部&&内部命令替换

  • :shell 交互式shell
    :!cmd 执行cmd并输出结果
    :! 执行上一次的命令
    :r[ead] !cmd当前光标写入命令结果
    :上下方向键 查找命令
    :[range]co[py] {address} 复制指定范围的行到指定地址,简写为t 理解为copyto
    :[range]m[ove] {address} 移动命令
    :@:重复VIM命令,.重复普通命令
    Ctrl+D补全命令
    :[range] delete [x]
    :[range] yank [x]
    :[range] put [x]
    :[range] copy {address}
    :[range] move {address}
    :[range] normal {commands}
    :[range] join
    :[range] substitute/{pattern}/{string}/[flags]
    :[range] global/{pattern}/[cmd]

选项设置

  • set xxx 设置某项
    set noxxx 取消某项设置
    set xxx! 反置某项值
    set xxx& 恢复默认值
    set xxx? 查询当前状态+
    setlocal 局部有效,set全局有效+
    :set expandtab 将tab转换为space
    :set tabstop=4 制表符宽度 tabstop=4或ts=4
    :retab 按照设定值重新缩进
    :set shiftwidth=4 行缩进时宽度
    :set ai 自动缩进

代码格式化

  • =全文格式化 gg=G,比如粘贴的内容
    当前行格式化缩进 ==
    当前光标所在行的后N行格式化 N==
    选中行格式化,=

原文来自:http://www.codeceo.com/article/vim-common-operating-commands.html

本文地址: https://www.linuxprobe.com/vim-mingling.html编辑员:姜显赫,审核员:逄增宝

本文原创地址:https://www.linuxprobe.com/vim-mingling.html

篇我们来谈论vim一个相当重要的东西——自动命令。

从编程的角度来看,自动命令有点类似于事件响应,或者回调函数之类。当外部发生某些事件的时候,自动执行事先定义好的一组命令。

定义一个自动命令的格式如下

autocmd type pattern cmd
  • autocmd: 自动命令以 autocmd 关键字开始,它的作用类似与 js 中定义函数时使用的 function 关键字
  • type: 触发该命令的事件类型
  • pattern: 事件的过滤,根据不同的事件类型有不同的含义
  • cmd : 将要执行的命令

说了这么多,我们以一个例子来说明:
当我们使用
vim 打开一个不存在的文件,如果直接退出,我们会发现它并没有被保存。因为打开一个不存在的文件时 vim 并没有真的在磁盘中创建这么一个文件,它仅仅新开了一个缓冲区,当执行写命令的时候才真正会创建文件。我们使用 q! 退出的话,它是不会往文件中写的

我们来试试修改这一行为,打开新文件的时候就创建,也就是打开一个新文件的时候就执行写操作。打开新文件的事件使用 BufNewFile 来表示。这里我们不限定文件格式,因此 pattern 这块就使用 * 来表示,执行的命令是 :w 来写入。

:autocmd BufNewFile * w

自动命令的事件类型

自动命令可以监听的事件类型主要有以下几种

  • 开始编辑一个当前并不存在的文件,也就是我们上面介绍的一种情况。这种情况使用 BufNewFile 来表示
  • 开始编辑一个已存在的文件。这种情况使用 BufReadPre 或者 BufReadPost 来表示。他们分别表示文件内容被加载前和被加载后
  • 改变一个缓冲区的 filetype 选项的时候,它与 vim 的文件类型配合使用。这种情况使用 FileType 来表示
  • 文件被写回磁盘。这种情况用 BufWritePreBufWritePost。他们的含义与上面 BufReadPreBufReadPost 类似。
  • 进入和退出插入模式,进入插入模式时使用 InsertEnter,退出插入模式时使用 InsertLevel
  • Vim 完成启动所有初始化操作之后可以使用 VimEnter 来表示
  • 输入可以使 vim 退出的命令,可以使用 ExitPre 来表示。如果输入 :quit ,在决定是否退出之前,可以使用 QuitPre

这些只是 vim 庞大事件中的一小部分,想要了解其他的事件,可以使用 :help autocmd-events

同时绑定多个事件

我们可以同时绑定多个事件,事件之间使用逗号作为分割即可,例如我们想要在写入或者加载HTML文件之前对其进行自动排版,那么就可以使用如下代码

:autocmd BufReadPost,BufWritePre *.html normal gg=G

自动命令它是在事件触发时,执行命令。相当于我们在命令模式下手动输入命令。在之前介绍命令模式的时候说到过,要在命令模式下使用普通模式的操作可以使用 normal。gg表示将光标移动到第一行,=G表示从当前光标到最后一行执行自动排版的操作。

我们在 html 文件中输入

<html>
<body>
    <div>
<div>
        <p>hello!</p>
</div>
    </div>
</body>
</html>

执行 :w之后我们发现它自动排版了。或者我们也可以使用 :edit打开一个排版混乱的HTML文件,会发现vim自动为它排版了。


或者我们再举一个例子,我们在之前设置了自动换行功能,因为在一般的编程语言中,一行代码写太长确实不是一个好习惯。但是像
markdown 或者 html 这种用来写文档的标记语言,难免会出现很长的文本,这个时候再设置自动换行就有点不合适了,我们可以使用下面的语句来针对这两种文档来消除

:autocmd BufNewFile, BufReadPost *.html setlocal nowrap

这里我们使用 BufNewFile和 BufReadPost,因为我们需要对新创建的和已存在的 html文件都启用该设置。

FileType 事件

这种类型的事件可以说是我们最常用的,通过这个事件配合 setlocal 可以很方便地针对不同的编程语言做不同的设置
例如我们将上述取消 HTML 自动换行的代码做一个改写,改写成使用 FileType

:autocmd FileType html setlocal nowrap

又或者我们可以根据不同的语言,定义一个快捷键快速添加注释

:autocmd FileType python nnoremap <buffer> <localleader>c I#<esc>
:autocmd FileType javascript nnoremap <buffer> <localleader>c I//<esc>

在输入完命令之后,我们新打开一个 js或者 python文件,就可以直接测试


我们也可以结合之前介绍过的本地缩写的定义,针对不同的文件类型定义不同的缩写,例如

:autocmd FileType c iabbrev <buffer> main int main(int argc, char* argv[])
:autocmd FileType python iabbrev <buffer> main if __name__ == "__main__":

针对不同语言快速填充main函数。

我们结合FileType 事件和缩写似乎可以针对不同语言定义出对应的代码片段,这个也就是有的编辑器提供的 code snippet 的功能,结合插件我们可以使用 vim 定义出更加强大的代码片段

自动命令组

已经讨论了自动命令的这么多东西了,各位小伙伴可能已经掌握了甚至已经开始迫不及待想往配置文件里面添加内容了。但是在 lua中该怎么使用自动命令呢?先别着急,自动命令相关内容还没讨论完,先容我卖个关子,我们在后面来讨论如何在 lua中添加自动命令吧。

我们暂时不讲如何在 lua 中添加自动命令,这里我们先尝试启用 init.vim 文件。我们在里面加入一行

autocmd BufWrite * sleep 200m

然后我们保存并使用 :source $MYVIMRC启用

好像也没什么变化是不是。别着急,我们多次执行 :source $MYVIMRC。然后再执行保存操作。是不是发现vim越来越慢了。这是怎么回事呢?

我们每次执行 :source $MYVIMRC 的时候,vim 不会丢弃原有的设置,只会重头再来读取并加载新的设置,有点像文件的追加。在多次加载配置文件的时候,vim 已经创建了多个自动命令了。随着加载次数的增多,vim 中保存了多个休眠的自动命令了。所以 vim 会变得越来越卡。

你可能会说,谁没事闲着一直加载配置文件玩啊,而且也没有人会写延时吧。但是想想这个场景是不是像我们在反复修改并测试配置的时候会做的操作。虽然我们不会做延时,但是加载配置或者加载插件也是要时间的,插件有的也会执行自动命令,如果数量大起来了,自然会影响vim的启动速度。

我们该如何处理这个问题呢?

vim中给出的解决办法是将自动命令放到一个用户命名的组中,组成一个自动命令组。

使用关键字 augroup 来创建一个自动命令组。例如我们可以创建下面的自动命令组

:augroup testgrp
:    autocmd BufWrite * echom "hello1"
:    autocmd BufWrite * echom "hello2"
:augroup END

直接在命令行输入这么些东西太麻烦了,我们还是在 init.vim 中输入。启用之后我们再来执行保存操作接着,执行 :message 命令来查看日志,发现有两条打印

我们再来修改一下配置文件或者在命令行输入添加下面一句

:augroup testgrp
:    autocmd BufWrite * echom "hello3"
:augroup END

我们先退出vim,再打开,然后执行保存操作,再看看日志里面有几条输出呢?

答案可能会另各位百思不得其解,它会打印三条。并不是各位想象的那样,同名的组发生覆盖。这里它也会发生追加现象,将同一组的多个命令组合在一起。既然用不用组都会追加,那么我要它有何用,我还多写了这么多代码。别着急,我们慢慢往下看。

分组一个是为了划分模块,第二个原因就是我们可以使用 autocmd! 来清除同一组之前的命令。
例如我们将上述命令修改为

:augroup testgrp
:    autocmd!
:    autocmd BufWrite * echom "hello3"
:augroup END

这个时候再次测试,我们发现它只会打印一条语句了。

但是这里如果我们将它放在不同组的时候,情况就又发生变化了

:augroup testgrp
:    autocmd BufWrite * echom "hello1"
:    autocmd BufWrite * echom "hello2"
:augroup END

:augroup testgrp1
:    autocmd!
:    autocmd BufWrite * echom "hello3"
:augroup END

我们发现在保存之后,它还是会打印3条语句


autocmd! 只会清除同一组之前的所有命令,而不同组的命令它不会生效。这就给我们按模块划分命名提供了便利。

改进自动加载配置文件的操作

之前我们通过绑定快捷键 <leader>ss来自动重新加载配置,学习了自动命令之后我们可以进一步的偷懒了,利用自动命令,我们可以做到只要配置文件被保存了,就自动加载。

:augroup NVIMRC
:    autocmd!
:    autocmd BufWritePost init.vim source %
:augroup END

这里我们先使用 autocmd!清除之前的加载操作。后面的自动命令中,我们使用 BufWritePost在配置文件保存到磁盘之后再来执行加载操作,保证从磁盘中加载到的配置文件与我们修改过后的保持一致。

自动命名在我们实现 vim 自动化编程的一个重要工具。甚至 vim 自身也有很多功能依靠它来实现,比如文件类型检测。文件类型检测我们将在下一章进行讨论。

累点滴,汇成江海。咱们从最最基础的PHP知识开始学习,一步一个脚印的开启PHP的学习旅途吧。

请点击右上角“关注”按钮关注我们哟:跟着木辛老师学习PHP编程知识,变身快乐的编程达人吧~

同学们好呀!木辛老师又来了。

咱们在开始PHP的学习之前,需要先准备一个可以提供PHP服务的Web服务器。我们就复用木辛老师专栏中的一个教程,使用Homestead本地开发环境进行学习呗。

传送门:《Laravel第一课:搭建Laravel开发环境》

也可以关注木辛老师的Laravel专栏哟:

大家配置好本地开发环境以后,还需要稍微设置一下,针对这个项目,在Homestead配置文件中作如下设置,

添加指向当前项目根目录的配置:

sites:
 - map: learning_php.test to: /Code/zyoo/learning_php
 to: /Code/zyoo/learning_php

另外还需要在本机hosts文件中添加一个域名指向:

sudo vim /etc/hosts

并添加如下记录:

192.168.10.10 learning_php.test

最后,添加一个测试文件:

php代码

然后,打开浏览器,访问域名查看页面结果

执行效果

大家可以看到,我们已经可以成功的访问到测试用的PHP文件了。

好了,万事俱备,只需要学习了。那么,咱们开始吧~

创建示例应用:木辛老师的图书馆

几乎绝大部分服务器端的脚本语言最初设计的应用场景之一就是处理HTML表单。木辛老师要翻出家底,将自己最心爱的在线图书商城,用来作为学习PHP基础知识的场景吧。

创建订购图书用的订单表单

通过这个表单页面,我们可以知道顾客订购的商品,订单的金额以及其他一些附属信息。HTML代码请看下方:

<html>
 <head>
 <title>木辛老师的PHP基础入门教程</title>
 </head>
 <body>
 <form action="processorder.php" method="POST">
 <table style="border: 0px;">
 <tr style="background: #cccccc">
 <td style="width: 150px;text-align:center;">图书名称</td>
 <td style="width: 50px;text-align:center;">数量</td>
 </tr>
 <tr>
 <td>PHP入门指南</td>
 <td><input type="text" name=“book_name_01" size="3" maxlength="3"/></td>
 </tr>
 <tr>
 <td>PHP和MySQL开发</td>
 <td><input type="text" name="book_name_02" size="3" maxlength="3"/></td>
 </tr>
 <tr>
 <td>Laravel入门</td>
 <td><input type="text" name="book_name_03" size="3" maxlength="3"/></td>
 </tr>
 <tr>
 <td colspan="2" style="text-align: center;">
 <input type="submit" value="提交订单"/>
 </td>
 </tr>
 </table>
 </form>
 </body>
</html>

咱么直接通过浏览器访问这个HTML页面,看看效果:

页面显示

哈,简单的页面,我们已经开启Web开发神秘旅程了。继续加油!

大家可能注意到了一个细节:在html代码的form表单部分,action属性我们指向了一个php脚本:

<form action="processorder.php" method="POST”>

具体的PHP脚本的学习我们很快就能看到。这里只是稍微提一下,这个action属性值就是用户点击“提交订单”按钮时将要请求的URL。

用户在表单中输入的数据,会以POST的方式,发送给URL指向的PHP文件进行处理。

表单处理

那如何处理这个表单呢?又如何让PHP代码起作用的?

要处理这个表单,我们需要创建一个php文件,它的名字需要和form中action属性的值保持一致。

那么,我们就创建一个名字叫做processorder.php的文件吧。

代码可以先这么写,看看是否能起作用哈:

<html>
 <head>
 <title>订单处理结果</title>
 </head>
 <body>
 <h1> 木辛老师的在线图书馆</h1>
 <h2> 订单处理结果通知</h2>
 <?php echo '<p>订单已处理完成</p>'; // 这里是PHP的代码 ?>
 </body>
</html>

保持文件,并刷新页面。这个时候我们点击“提交订单”按钮,效果如下:

php执行结果

大家可以看到,红框部分就是通过PHP代码输出的结果。这样,我们就实现了通过Web方式执行了PHP代码的需求,这么一看PHP还是非常简单的吧。

我们顺便在看看这个页面的源代码吧,看一下PHP代码如何在HTML页面中完成任务的吧:

源代码

通过页面源码,我们发现刚才写的PHP代码已经不见了,取而代之的是

<p>订单已处理完成</p>

这是怎么回事呢?

这是因为PHP解释器在脚本运行的时候,将该脚本的输出替代了脚本自身的代码,通过这种方式,就可以生成可以在任何浏览器上运行的HTML页面了。也就是说,浏览器是不需要学会PHP的。

通过这段代码,我们可以学习一些PHP的基础知识:

  1. PHP标记
  2. PHP语句
  3. 如何空格
  4. 添加注释

PHP标记

第一种情况:在HTML中混写PHP和HTML代码,需要为php添加标记。PHP代码会以“<?php”作为开始,以“?>”作为结束。这些符号就叫做PHP标记,它们主要用来告诉服务器PHP代码的开始和截止,在这两个起止符号之间的任何代码,服务器都会以PHP语法来解析。

另一种情况:之后,我们写纯PHP的时候,每个文件也需要添加PHP标记。不过呢,结束标记可以省略,这也是很大一部分PHPer默认遵守的规则。

PHP语句

在PHP的开始和截止标记之间,就是PHP语句了,通过这些内容可以告诉PHP解释器应该进行如何的操作,在我们这个例子里,通过:

echo '<p>订单已处理完成</p>’;

使用echo语句完成了一个非常简单的操作,仅是将echo后边的字符串原样打印到浏览器中。这里需要特别注意的一点就是每个PHP语句后边都需要添加英文的分号作为语句的结束符,否则会出现错误,但是在这个html页面中,因为只有一句代码,忽略掉分号也是不会报错的。

但是还是强烈建议大家养成习惯:每句PHP代码结束都要以分号结尾哟!

空格

一般情况下,为了让代码更加清晰和整洁,在编码的过程中会添加一些空格,这些空格包括:回车换行、空格、制表符等都被认为是空格。

当然了,浏览器并不会在意你是否输入了空格,同样的PHP服务器端解析器也会忽略这些,这些空格仅是给编写代码的人看的。

但是,木辛老师还是再次强烈建议,在代码的适当位置添加空格或者空行,这样做可以很有效的提升代码的可阅读性,方便后期的维护工作。

注释

最后在讲讲注释,理论上在编程中出现频率非常高的一个知识点。

为什么说理论上呢,因为这么重要的一个要点,在实际开发中很容易被广大开发者忽略呢!

由于种种原因吧,开发者很不习惯在开发过程中写非常详尽的注释,而且有时候在Git提交时也是草草的一笔带过。这样做的后果就是,若干时间后,当你再次拿到这段代码,可能会花费更多的时间梳理它。

所以,善于写注释,也是提高生产效率的一种有效手段。

PHP解释器同样会在执行的时候忽略掉注释,也就是说就好比像空格一样,PHP解析器会跳过注释,它只负责执行PHP代码!

PHP脚本中的注释比较丰富,有很多类似C语言的风格,比如:

多行注释:

/* 这是
 一个
 多行
 注释
/*

可以看出来,多行注释以 /*开始,以*/结束。同样的和C语言是一样的,多行注释是不能嵌套的。

当然了,除了多行注释之外,也支持单行注释:

echo '<p>订单已处理完成</p>'; // 这里是PHP的代码

或者这种:

echo '<p>订单已处理完成</p>’; #这里是PHP的代码

不论采取哪种风格的注释,在注释符号之后的所有内容,PHP解释器都会认识不需要处理的,这一点一定要注意呀!

好了,今天的课程咱就先讲到这里。

小朋友们不要忘记关注我们哟 ,下期课程更精彩,请大家一起期待吧~

快乐编程,快乐成长,拜拜!