[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

用 VIM 编程时自动扩展小括号和大括号的方法



我想实现在编辑 C 代码时,输入 ife<空格> 之后,代码自动扩展为:
    if (<光标>) {
    } else () {
    }

于是我设置了:
inoremap ife<SPACE> if<SPACE>()<SPACE>{<ENTER>}<SPACE>else<SPACE>{<ENTER>}<ESC>2k4li 

然而当我正常输入一个字符串时,例如 my life with ,代码会自动扩展为:
    my lwith if () {
    } else {
    }

这个结果并非是我所希望看到的。如果我使用 inoreabb 来设置的话:
inoreabb ife if<SPACE>()<SPACE>{<ENTER>}<SPACE>else<SPACE>{<ENTER>}<ESC>2k4li 

虽然不会遇到刚才那个问题,但是新的问题是,我不知道怎样才能在 ife
后面简便的输入一个真正的<空格>。 

最终还是决定使用 inoremap ,通过匹配光标所在行的内容解决了上述相似的问题。

$ cat ~/.vim/ftplugin/c.vim
inoremap if<SPACE> <ESC>:call If()<CR>a
inoremap else<SPACE><SPACE> <ESC>:call Else()<CR>a 

function! If()
    iunmap if<SPACE>
    if (getline('.') =~ '^\s*$')
        exec "normal ddO
                    \if () {\n}
                    \\e1k3la"
    elseif (getline('.') =~ '^\s*}\s*\<else\>\s*$') 
        exec "normal a
                    \if () {\n}
                    \\e1k10la"
    elseif (getline('.') =~ '^\s*}\s*\<else\>.*{\s*$')
        exec "normal a
                    \if () {\n} else 
                    \\e1k4la"
    else
        exec "normal a
                    \if "
    endif
    inoremap if<SPACE> <ESC>:call If()<CR>a
endfunction

function! Else() 
    iunmap else<SPACE><SPACE>
    if (getline('.') =~ '^\s*}\s*$')
        exec "normal a
                    \else {\n}
                    \\eO?\eC"
    else
        exec "normal a 
                    \else "
    endif
    inoremap else<SPACE><SPACE> <ESC>:call Else()<CR>a
endfunction

效果像下面描述的这样:
1. 我习惯开括号和 if 放在同一行,所以在一个新行上输入 if<空格>
后,代码自动扩展为: 
    if (<光标>) {
    }

2. 我习惯把 else 和 if
的闭括号放在同一行,所以如果光标左边是闭括号,在光标位置输入 else<空格><空格>
后,代码自动扩展 为:
    } else {
        <光标>
    }

3. 如果光标左边是 else ,右边是开括号 { ,例如:
    } else <光标> { 
        ... // 内容
    }

    当输入 if<空格> 后,代码自动扩展为:
    } else if (<光标>) {
    } else {
        ... // 原内容
    }

4. 如果光标左边是 else ,右边没有开括号,例如:
    if (foo > 0) {
        ... // 内容 
    } else <光标>

    当输入 if<空格> 后,代码自动扩展为:
    if (foo > 0) {
        ... // 内容
    } else if (<光标>) {
    }

相似的关键字如 #define, #include, for, switch 等,我想都可以如此实现。 

-- 
Vern
2007-12-09

Attachment: signature.asc
Description: Digital signature


Reply to: