[vim实用技巧读书笔记] vim中的模式以及其中的技巧

来源:互联网 发布:php空间试用 编辑:程序博客网 时间:2024/06/17 18:00
--------------------------------------------------------------NORMAL MODE----------------------------------------------------------
1. 使用vim时大多数的时间应该都处于这个模式,所以称为自然模式
    the better you know vim, the less time you will spend in insert mode.

2. 使用hjkl代替上下左右键
    Type g before h, j, k or l to move by screen lines instead of virtual lines.
    <Type g before r or R to virtual Replace mode instead of normal Replace mode.>  
   f {char} 跳到当前行的某个字符上,然后用 ; 和 , 命令相应地正向或反向重复此跳转;

3. 执行、重复、回退粒度尽量小
    .(a period) 重复上次命令模式模式之外的命令,u撤消修改
    每次undo的单位是普通模式、可视模式以及命令行模式中所触发的命令或者 i{insert sometext}<Esc>;
    把每次i和Esc之间的输入当成一个原语来对待,上下左右键会破坏这种原语
    构造可重复的修改,每次的修改尽量要可被下次dot命令重用(:h aw)

4. 命令前使用次数指定命令执行多少次
    巧用次数做简单的算术运算<C-a> 和 <C-x> 命令分别对数字执行加和减操作( :h ctrl-a); 如果光标不在数字上,那么 <C-a> 命令将在当前行正向查找一个数字
    能够重复,就别用次数只在必要时使用次数,如:把文字“I have a couple of questions”改为“I have some more questions”


---------------------------------------------------------PENDDING  MODE-----------------------------------------------------------
1.  操作符+ 动作命令 = 操作  (:h operator)
        c{motion} Change the text moved over by {motion} and insert text to replace it.
        d{motion} same as c{motion}, but doesn't enter insert mode.
       y{motion} copy the text moved over by {motion}. 
        gu, g~, gU change case 
        > 增加缩进
        < 减少缩进
        = 自动缩进
        !  提供外部程序的输入
        创建自定义操作符(:h :map-operator)
        创建自定义动作命令(:h omap-info

2. 能少码字的尽量不码字
        x 代表dl(删除当前光标下的字符)
        X 代表dh(删除当前光标左边的字符)
        D 代表d$(删除到行尾的内容)
        C 代表c$(修改到行尾的内容)
        s 代表cl(修改一个字符)
        S 代表cc(修改当前行)
        Y 代表yy(复制当前行)

-----------------------------------------------------------INSERT MODE-------------------------------------------------------------
1. 在插入模式中可即时更正错误
        <C-h>  删除前一个字符(同退格键)
        <C-w>  删除前一个单词
        <C-u>  删至行首

2. 插入模式下也可以进行粘贴操作
        <C-r>{register} ( :h i_CTRL-R)
        其插入方式就如同这些文本是由键盘上一个个输进来的,所以会受 ‘ textwidth ’ 或者‘ autoindent ’影响,
        寄存器里粘贴很多行文本的话使用<C-r><C-p>{register} (:h i_CTRL-R_CTRL-P)或切换到普通模式操作
        
        我们可以用 = 符号指明使用表达式寄存器。在插入模式中,输入 <C-r>=  就可以访问这一寄存器,
        大部分的 Vim 寄存器中保存的都是文本,表达式寄存器则是个另类,它执行一段 Vim 脚本,并返回其结果

3. 插入模式-->普通模式
        <Esc>  切换到普通模式,任何模式下都可以使用Esc返回到普通模式下!
        <C-[>  切换到普通模式 ( :h i_CTRL-[
        <C-o>  切换到插入-普通模式 ( 临时切换到普通模式 :h i_CTRL-O
        比如: <C-o>zz可以滚动窗口,然后返回插入模式

4. 用字符编码插入非常用字符
        <C-v>{123}  以十进制字符编码插入字符
        <C-v>u{1234}  以十六进制字符编码插入字符  
        <C-v>{nondigit}  按原义插入非数字字符   ( :h i_CTRL-V_digit)
        <C-k>{char1}{char2}  插入以二合字母{char1}{char2}表示的字符,:digraphs可查组合列表 (:h digraphs-default   :h digraph-table
        字符-->编码: ga (:h ga

-------------------------------------------------------VISUAL MODE--------------------------------------------------------------
1.  选择高亮选区
        v  激活面向字符的可视模式
        V  激活面向行的可视模式
        <C-v>  激活面向列块的可视模式
        gv  重选上次的高亮选区
              
        <Esc> / <C-[>    回到普通模式
        v / V /<C-v>    切换到普通模式(在对应的面向字符可视模式、面向行的可视模式或面向列块的可视模式中使用时)
        o   切换高亮选区的活动端

------------------------------------------------------EX      MODE------------------------------------------------------------------
1. 命令行模式 
    vim和emacs都有类似的命令行,vim-->vi-->ex-->ed,所以vim的命令行模式中执行的命令又被称做 Ex 命令:h ex-cmd-index
    Ex命令不受光标位置的影响,可以运筹帷幄于千里之外!:执行命令命令重复使用 @:,回退位置使用<C - o>,u回退修改
    
2. Vim 为几乎所有功能都提供了相应的 Ex 命令
下面是
操作缓冲区文本的 Ex 命令:
            :[range]delete [x]  删除指定范围内的行[到寄存器 x 中]
            :[range]yank [x]  复制指定范围的行[到寄存器 x 中]
            :[line]put [x]  在指定行后粘贴寄存器 x 中的内容
            :[range]copy {address}  把指定范围内的行拷贝到 {address} 所指定的行之下
            :[range]move {address}  把指定范围内的行移动到 {address} 所指定的行之下
            :[range]join  连接指定范围内的行
            :[range]normal {commands}  对指定范围内的每一行执行普通模式命令 {commands}
            :[range]substitute/{pattern}/{string}/[flags]把指定范围内出现{pattern}的地方替换为{string}
            :[range]global/{pattern}/[cmd]  对指定范围内匹配{pattern}的所有行,在其上执行Ex 命令{cmd}
    
3. 编辑快捷键:
   用 <C-w> 和 <C-u>分别删除至上个单词的开头及行首
   用 <C-v> 或 <C-k> 来插入键盘上找不到的字符 (参见14用字符编码插入非常用字符
   用 <C-r>{register} 命令把任意寄存器的内容插入到命令行
        
4. Ex命令一般前面是作用范围,可以用行号、位置标记或是查找模式来指定范围的开始位置及结束位置
    1  文件的第一行
   $  文件的最后一行
   0  虚拟行,位于文件第一行上方
   .  光标所在行
   'm  包含位置标记 m 的行
   '<  高亮选区的起始行
   '>  高亮选区的结束行
   %  整个文件(:1,$ 的简写形式)
   /pattern/ 匹配pattern的行         
   n+offset 代表用偏移对地址修正
              
5. 使用‘:t’和‘:m’命令复制和移动行
    :copy 命令(及其简写形式 :t )让我们可以把一行或多行从文档的一部分复制到另一部分
    :t 命令的一些应用实例,复制距离较远的行时, :t 命令通常更加高效
        命令  用途
        :6t.  把第 6 行复制到当前行下方
        :t6  把当前行复制到第 6 行下方
        :t.  为当前行创建一个副本(类似于普通模式下的 yyp, yyp 会使用寄存器,而 :t. 则不会
        :t$  把当前行复制到文本结尾
        :'<,'>t0  把高亮选中的行复制到文件开头
    :move 命令则可以让我们把一行或多行移到文档的其他地方

6. 在指定范围上执行普通模式命令
    Ex 命令可以一次修改若干行,而 :normal 命令则让我们可以把具有强大表现力的 Vim 普通模式命令与具有大范围影响力的 Ex 命令结合在一起,这种结合真地是珠联璧合!
    :%normal A;  在文件的每行结尾都添加一个分号
    :%normal i//   把整个c文件都注释掉

7. 有命令行的地方就有命令补全和历史记录
    <Tab> 键自动补全命令
    <C-d> 命令会让 Vim 显示可用的补全列表(:h c_CTRL-D)
    多次按 <Tab> 键遍历补全列表, <S-Tab>反向遍历
    创建自定义 Ex 命令时定义该命令的 Tab 键补全行为(:h :command-complete)

    历史记录是可以跨会话的,所以可以尽量设置大点(:h viminfo)
    : xx然后按 <Up> 键或都<Down> 键遍历以xx开头的历史命令
    <C-p> 和 <C-n> 组合键来反向或正向遍历命令历史,但是不过滤以xx开头的命令
    /搜索历史也可以使用<Up> <Down>遍历历史查找

8. 命令行窗口
    q:打开命令行窗口(:h cmdwin)
    命令行窗口就像是一个常规的 Vim 缓冲区,只不过它的每行内容都对应着命令历史中的一个条目,
    在按下 <CR> 键时,将会把当前行的内容当成Ex 命令加以执行
    当命令行窗口处于打开状态时,它会始终拥有焦点,除非关闭命令行窗口,否则我们无法切换到其他窗口。
    q/  打开查找命令历史的命令行窗口
    q:  打开 Ex 命令历史的命令行窗口
    <Ctrl-f>  从命令行模式切换到命令行窗口.

9. 把当前单词插入到命令行
    <C-r><C-w> 映射项会复制光标下的单词并把它插入到命令行中
    <C-r><C-w> 映射项会复制光标下的字串并把它插入到命令行中(:h c_CTRL-R_CTRL-W
    * 命令等效于输入 /\<<C-r><C-w>\><CR> 序列
    应用场景: vimrc中 :help <C-r><C-w> 你就可以查阅该光标下设置的文档了

10. 执行 Shell 中的程序
    :!{cmd} 在 shell 中执行 {cmd},这种语法适用于执行一次性命令; :shell  启动一个 shell (输入 exit 返回 Vim)
    在 Vim 的命令行中,符号 % 代表当前文件名( :h cmdline-special)
    从当前文件名中提取出诸如文件路径或扩展名之类的信息(:h filename-modifiers 
    :shell 命令来启动一个交互的 shell 会话(:h :shell)
    :read !{cmd} 命令,把 {cmd} 命令的输出读入当前缓冲区中(:h read!)
    :[range]write !{cmd}  在 shell 中执行 {cmd} ,以 [range] 作为 {cmd} 的标准输入( :h :write_c)( :h rename-files
    :write! sh 表示把缓冲区内容写到一个名为sh的文件,!表示强制写入
    :[range]!{filter cmd}表示,由 [range ]所指定的行会传给{cmd} 作为标准输入,然后又会用 {cmd} 的输出覆盖 [range] 内原本的内容( :h :range!
    !{motion}操作符切换到命令行模式,并把指定 {motion} 所涵盖的范围预置在命令行上(:h !)
0 0