vim tips

10.8

sub-replace-expression

When the substitute string starts with "\=" the remainder is interpreted as an expression.

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

Algin text after :

abc: 1,
b: 2345,

->

abc: 1,
b:   2345,

Use https://github.com/godlygeek/tabular

'<,'>Tabularize /:\s*\zs\S.*

Read cmd output

:read !pwd

pwd | vim

Use neovim from vim

Add ~/.config/nvim/init.vim

set runtimepath^=~/.vim runtimepath+=~/.vim/after
let &packpath = &runtimepath
source ~/.vimrc

Buffers

:buffers[!] [flags] where [flags] restricts the buffers to be listed. For example

" Show all active buffers
buffers! a

" Show regular active buffers
buffers a

" Show special(unlisted) active buffers
buffers au

You can also :filter buffers by displayed buffer name

filter /\.vim/ buffers a

Also getbufinfo()

for buf in getbufinfo()
  echom buf.bufnr.': '.buf.name
endfor

sudo vim got incorrect config

Use sudoedit instead of sudo vim

Command completion menu

set wildmenu
set wildmode

syntax sync

当文件较大时,syntax sync 定义了翻页滚动时刷新语法高亮的机制。否则有时候会出现空白语法高亮。

参考

查看和清除

" 查看
syntax sync

" 清除
syntax sync clear

sync 机制

不同的机制在性能和可靠性方便有所不同

  • 从头开始高亮

    syntax sync fromstart
    
  • 从注释开始高亮

    syntax sync ccoment javaScriptComment
    
  • 基于模式匹配

    syntax sync match <syncName> groupthere <name> <pattern>

      - `syncName` 语法名,可以任意
      - `name`, `pattern` 为开始同步位置的语法名和匹配模式
    
          ```vim
          syntax sync match htmlHighlight groupthere NONE "<[/a-zA-Z]"
          syntax sync match htmlHighlight groupthere javaScript "<script"
          syntax sync match htmlHighlightSkip "^.*['\"].*$"
          ```
    
  • 控制同步行数

    syntax sync minlines=10
    syntax sync maxlines=200
    

使用外部命令来缩进、格式化代码

  • equalprg

    for =

    setlocal equalprg=prettier\ --parser\ typescript
    setlocal equalprg=prettier\ --parser\ vue
    
  • formatprg

    for gq

Timer

  • timer_start({time}, {callback}[, {options}])
  • timer_stop({timer})
  • timer_stopall()
function! MyOtherFunction(id)
  echom a:id
endfunction
call timer_start(1000,  'MyFunction')
function! MyOtherFunction(arg, id)
  echom a:arg
endfunction

call timer_start(1000, function('MyOtherFunction', [arg]))

Events

Scripting the Vim editor, Part 5: Event-driven scripting and automation

Event sequence in a simple Vim editing session

> vim
    BufWinEnter     (create a default window)
    BufEnter        (create a default buffer)
    VimEnter        (start the Vim session)

:edit example.txt
    BufNew          (create a new buffer to contain demo.txt)
    BufAdd          (add that new buffer to the session's buffer list)
    BufLeave        (exit the default buffer)
    BufWinLeave     (exit the default window)
    BufUnload       (remove the default buffer from the buffer list)
    BufDelete       (deallocate the default buffer)
    BufReadCmd      (read the contexts of demo.txt into the new buffer)
    BufEnter        (activate the new buffer)
    BufWinEnter     (activate the new buffer's window)

i
    InsertEnter     (swap into Insert mode)

Hello
    CursorMovedI    (insert a character)
    CursorMovedI    (insert a character)
    CursorMovedI    (insert a character)
    CursorMovedI    (insert a character)
    CursorMovedI    (insert a character)

<ESC>
    InsertLeave     (swap back to Normal mode)

:wq
    BufWriteCmd     (save the buffer contents back to disk)
    BufWinLeave     (exit the buffer's window)
    BufUnload       (remove the buffer from the buffer list)
    VimLeavePre     (get ready to quit Vim)
    VimLeave        (quit Vim)

Autocmd

手动触发事件

doautocmd {event} [fname]

doautoall {event} [fname]

单个命令忽略事件

noautocmd w fname.gz

Print file

hardcopy

hardcopy

PSUtils

PSUtils: http://knackered.org/angus/psutils

curl ftp://ftp.knackered.org/pub/psutils/psutils.tar.gz
tar -xzf psutils.tar.gz
cd psutils
cp Makefile.unix Makefile
# Alter required paths in Makefile 
make
sudo make install

手动双面打印的例子

hardcopy > test.ps
psselect -o test.ps odd.ps
psselect -e test.ps even.ps

先打印 odd.ps,把打了单面的纸放回去再打印 even.ps。注意方向和正反面。可能需要旋转 180 度。

TOhtml

Tohtml

浏览器打开生成的文件,调用打印功能

Vanilla vim

Useful for debug

vim -u NONE

setf type

set filetype=type不同,setf type 可以避免重复设置类型,进而避免触发多次加载。

Jump to last position when reopening file

autocmd BufReadPost *
  \ if line("'\"") >= 1 && line("'\"") <= line("$") && &ft !~# 'commit'
  \ |   exe "normal! g`\""
  \ | endif

GVim guifont

if has("gui_running")
    if has("gui_gtk2")
        set guifont=Inconsolata\ 12
    elseif has("gui_macvim")
        set guifont=Menlo\ Regular:h14
    elseif has("gui_win32")
        set guifont=Consolas:h11:cANSI
    endif
endif

windows - set gvim font in .vimrc file - Stack Overflow

copy/paste in terminal vim

set clipboard=unnamedplus

save with sudo

:w !sudo tee %

^@ 符号

通过system运行外部命令并在 vim 中展示输出时,换行符会显示成^@。可以当成\n来替换。

let ouput = substitute(oupu, '\n', '', 'g')

嵌套语法高亮

可以使用 matchgroupcontains 关键字。注意,matchgroup 需要写在前面。

:sy region par1 matchgroup=par1 start=/(/ end=/)/ contains=par2
:sy region par2 matchgroup=par2 start=/(/ end=/)/ contains=par3 contained
:sy region par3 matchgroup=par3 start=/(/ end=/)/ contains=par1 contained
:hi par1 ctermfg=red guifg=red
:hi par2 ctermfg=blue guifg=blue
:hi par3 ctermfg=darkgreen guifg=darkgreen

查看加载脚本的位置

参考

" Relative path of script file:
let s:path = expand('<sfile>')

" Absolute path of script file:
let s:path = expand('<sfile>:p')

" Absolute path of script file with symbolic links resolved:
let s:path = resolve(expand('<sfile>:p'))

" Folder in which script resides: (not safe for symlinks)
let s:path = expand('<sfile>:p:h')

" If you're using a symlink to your script, but your resources are in
" the same directory as the actual script, you'll need to do this:
"   1: Get the absolute path of the script
"   2: Resolve all symbolic links
"   3: Get the folder of the resolved absolute file
let s:path = fnamemodify(resolve(expand('<sfile>:p')), ':h')

Boolean

Boolean 运算会先把变量转换成 Number。

  • Number

    非0为 True,0 为 False。

    返回值为 Boolean 时,True 返回 1,False 返回 0

  • String

    字符串先转换成数字。字符串以非0数字位开头时,为 True,否则为 False。

    "8foo" -> True "foo" -> False "0" -> False "0xf1" -> True

Number、String 互相转换

Number to String

转换成数字在 ASCII 中对应的表示

Number 123      --> String "123"
Number 0        --> String "0"
Number -1       --> String "-1"

String to Number

取字符串第一位转换成对应的数字。如果第一位不是数字,则为 0。支持二进制"0b10"、八进制"017"和十六进制"0xf9"

String "456"    --> Number 456
String "6bar"   --> Number 6
String "foo"    --> Number 0
String "0xf1"   --> Number 241
String "0100"   --> Number 64
String "0b101"  --> Number 5
String "-8"     --> Number -8
String "+8"     --> Number 0

syntax priority / order

PRIORITY :syn-priority

When several syntax items may match, these rules are used:

  1. When multiple Match or Region items start in the same position, the item defined last has priority.
  2. A Keyword has priority over Match and Region items.
  3. An item that starts in an earlier position has priority over items that start in later positions.

keepend 和 extend 实现嵌套语法高亮

混合使用 keepend 和 extend,可以实现嵌套的语法高亮。例如

:syn region xmlFold start="<a>" end="</a>" keepend extend

keepend保证了语法高亮不会超出匹配的范围之外。extend保证嵌套使用时,</a>仅仅会关闭对应的<a>

:h syn-extend

仅在 INSERT 模式启用输入法

set noimdisable

MacVim 需要取消 Preferences / AdvancedDraw marked text inline

Jump-motions / changelist

Jump: c-o, c-i

Changes: g;, g,

Speeds up / 加速

Refs

let loaded_matchparen=1 " Don't load matchit.vim (paren/bracket matching)
set noshowmatch         " Don't match parentheses/brackets
set nocursorline        " Don't paint cursor line
set nocursorcolumn      " Don't paint cursor column
set lazyredraw          " Wait to redraw
set scrolljump=8        " Scroll 8 lines at a time at bottom/top
let html_no_rendering=1 " Don't render italic, bold, links in HTML

Also see :help slow-terminal

显示 vim function 相关信息

:verb function MyFunction

测试脚本

vim 可以自动化读取文件和运行命令。

vim -es -u vimrc.vim -S cmds.vim test.vue

-e              Ex mode (like "ex")
-s              Silent (batch) mode (only for "ex")
-u <vimrc>      Use <vimrc> instead of any .vimrc
-S <session>    Source file <session> after loading the first file

save and edit

另存文件,编辑原文件

:w filename

另存文件,编辑新文件

:sav filename

vim-lsp

使用本地编辑器编辑远程文件

gvim scp://username@host[:port]//path/to/file

使用 modeline 自动设置文件的配置

在文件末尾添加。一般以注释加空格开头:

" vi:noai:sw=3 ts=6
" vim: tw=77

根据字符串获取和调用函数

:h function(
let func_name = 'MyFunc'
call function(func_name)(arg1, arg2)

清除语法高亮

某些文件开启语法高亮后导致卡慢,可以关闭当前 buffer 的语法高亮

syntax clear

关闭所有 buffer 的语法高亮

syntax off

函数参数数目不定

" a:0
" number of optional arguments
"
" a:1, a:2
" the optional arguments
function FunctionName(foo, ...)
    echo a:0
    echo a:1
endfunction

重定向 messages 到寄存器

参考

需要粘贴 messages 内容,但又无法直接复制,可以重定向到寄存器后粘贴出来

redir @*
messages
redir END

Clear messages

messages clear

输入特殊字符

vim 可以输入特殊字符,如希腊字母,数学符号等

Command mode 查看字符定义

digraphs

Insert mode 输入

<ctrl>kG*

imap 表达式

imap 可以映射成表达式,使用函数根据不同情况返回不同值

h <expr>

inoremap <expr> . InsertDot()

查看文本对应的 ASCII/Unicode 值

normal mode: `ga`

command mode: `:as`/`:ascii`

查看 vim 帮助

vim -h

vim 打开慢,性能分析

可以打印时间戳,找出慢的地方

echom strftime("%X %d %b %Y")

查看加载的脚本和顺序

scriptnames

语法高亮时间

:h syntime

性能分析

:h profile

记录 vim 启动时间信息到 vim.log

vim --startuptime vim.log

过多或重复的 autocmds

通过au查看所有定义的 autocmds。例如,输入

au CursorMoved

使用augroudautocmd!可以避免重复定义

命令模式快速移动

在命令界面,按 words 移动

<S-Right>
<S-Left>

按 Words 移动

<C-Right>
<C-Left>
📖