Vim映射Home键到首个非空字符

许多编辑器有相关选项,可以直接设置让 <Home> 键在首个非空字符和行首之间跳转。

Vim 也有快捷键,normal 模式下:

  • 0 跳转到行首;
  • ^ 跳转到首个非空字符;
  • $ 跳转到行尾。

目前未知跳转到最后一个非空字符的快捷键,有个网友提供了一个很好玩的技巧:

nmap <End> /\S\s*$<CR>:nohl<CR>
1

为了将 <Home>End> 键映射到其他编辑器常用的设置,我写了个可以用的代码,请高手不吝赐教。

" Dynamic bind <HOME> key
" if caret/cursor not at the frist non-white-space character
"   move caret/cursor to there
" else
"   move to beginning
function HomeBind(offset)
    let cursor=getpos('.')
    let s0=getline(line('.'))
    let s1=substitute(s0, "^\\s\\+", "", "")
    let x=len(s0)-len(s1)+1
    if col('.') == x-a:offset
        let x=1
    endif
    call setpos('.', [cursor[0], cursor[1], x, cursor[3]])
endfunction
imap <silent> <Home> <Esc>:call HomeBind(1)<cr>i
nmap <silent> <Home> :call HomeBind(0)<cr>
vmap <silent> <Home> <Esc>:call HomeBind(1)<cr>

" Dynamic bind <END> key
" if caret/cursor not at the end
"   move caret/cursor to there
" else
"   move to last non-white-space character.
function EndBind(offset)
    let cursor=getpos('.')
    let s0=getline(line('.'))
    let s1=substitute(s0, "\\s*$", "", "")
    let x=len(s0)+a:offset
    if col('.') == x
        let x=len(s1)+a:offset
    endif
    call setpos('.', [cursor[0], cursor[1], x, cursor[3]])
endfunction
imap <silent> <End> <Esc>:call EndBind(0)<cr>a
nmap <silent> <End> :call EndBind(0)<cr>
vmap <silent> <End> :call EndBind(0)<cr>
"nmap <End> /\S\s*$<CR>:nohl<CR>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

参考

这里还有几个实现很优雅,但稍有问题的脚本:

Help
[count]gg 跳转到第 [count] 行,默认第 1 行。
[count]G 跳转到第 [count] 行,默认最后一行。
[count]j 向下跳转 [count] 行,默认跳转一行。
[count]k 向上跳转 [count] 行,默认跳转一行。
/ 开始搜索。按 <Esc> 退出。
gh 跳转到首页。
gb 跳转到博客首页。
gw 跳转到 Wiki 首页。
gt 跳转到我的 Twitter Profile 页。
gp 跳转到我的 Github Profile 页。
? 打开帮助。按 <Esc> 退出。