GuoLi
10/26/2017 - 5:06 AM

VIM的应用技巧

VIM的应用技巧, vim

自动设置文件类型

比如在Jenkinsfile中,设置文件类型为groovy

// vi: ft=groovy

注意:在不同的文件类型内,要用对应的注释语句,比如在 python 文件内应该使用

# vi: ft=python

vim中dos换行符与unix换行符相互转换

set ff=unix
set ff=dos

将查找到的字符串改为大(小)写形式

" 全部大写
:g/string/s//\U\0\E/

" 首字母大写
:g/string/s//\u&/

\0&表示引用整个匹配字符串,\u表示下一个字符变为大写,\U表示其后字符变为大写,直到\e\E出现。具体内容可以查看帮助:h :s\=

执行外部命令

比如需要运行当前编辑的python代码

:!python %

!{cmd}在vim中执行外部命令(查看帮助:h :!),%为当前编辑的文件名(查看帮助:h cmdline-special:h :_%)。

使用sudo强制更新文件

:w !sudo tee %

w !{cmd}将整个buffer作为标准输入执行{cmd}(查看帮助:h :w_c),%为当前编辑的文件名,tee从标准输入读取内容后再将内容写到标准输出及文件中(类似T型三通)

对相同内容的行去重

:sort u

" 忽略大小写
:sort iu

统计个数

" 查看count-items帮助
:h count-items

" 查看s_flags了解替换标志
:h s_flags

" 使用substitute命令
:%s/./&/gn            " characters
:%s/\i\+/&/gn         " words
:%s/^//n              " lines
:%s/the/&/gn          " 'the' anywhere
:%s/\<the\>/&/gn      " 'the' as a word

将g/pattern/搜索到的行写入新文件

:redir > match.txt
:g/regex/
:redir END

要注意的是,:g/regex/w match.txt并不会将匹配的行写入新文件,而是在每次匹配到的行上执行w match.txt命令,并且是将当前buffer的所有内容写入新文件。

给每行自动编号

使用vim内置命令line(),用法可以查看帮助 :h line():h :.

:%s/^/\=line('.') . '、'/

'.'表示所在行的行号。当:s 命令的替换字符串以"\="开头时,表示以表达式的计算结果作为替换值,.用于连接字符串。

多行匹配(multiline match)

vim中默认是单行匹配,比如/hello\sworld/,只能匹配单行中"hello world",其中\s匹配空格或tab。如果希望多行匹配,可以使用/hello\_sworld/,这里的_s表示匹配空格、tab和换行符。

搜索/hello会在行首匹配到hello,搜索/hello$会在行尾匹配到hello。但是在模式/helloworld和/hello$world里的^和$只是普通字符,没有特殊含义。

  • \n a newline character (line ending)
  • \_s a whitespace (space or tab) or newline character
  • \_^ the beginning of a line (zero width)
  • \_$ the end of a line (zero width)
  • \_. any character including a newline

例如,搜索

  • /hello\n*world

    1. Finds hello followed by zero or more newlines then world.
    2. Finds helloworld or hello followed by blank lines and world.
    3. The blank lines have to be empty (no space or tab characters).
  • /hello\_s*world

    1. Finds hello followed by any whitespace or newlines then world.
    2. Finds helloworld or hello followed by blank lines and world.
    3. The blank lines can contain any number of space or tab characters.
    4. There may be whitespace after hello or before world.
  • /hello\_$\_s*world

    1. Finds hello at end-of-line followed by any whitespace or newlines then world.
    2. There must be no characters (other than a newline) following hello.
    3. There can be any number of space, tab or newline characters before world.
  • /hello\_s*\_^world

    1. Finds hello followed by any whitespace or newlines then world where world begins a line.
    2. There must be no characters (other than a newline) before world.
    3. There can be any number of space, tab or newline characters after hello.
  • /hello\_$world
    Finds nothing because \_$ is "zero width" so the search is looking for helloworld where hello is also at end-of-line (which cannot occur).

  • /hello\_^world
    Finds nothing because \_^ is "zero width" so the search is looking for helloworld where world is also at beginning-of-line (which cannot occur).

  • /hello\_.\{-}world

    1. Finds hello followed by any characters or newlines (as few as possible) then world.
    2. Finds helloworld or hello followed by any characters then world.
  • /hello\(\_s.*\)\{0,18\}\_sworld

    1. Finds a block of 0 to 18 lines enclosed by hello and world.
    2. limiting the number of lines is important, replacing this by a star will cause vim to consume 100% CPU.