You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Vim的inoremap <expr>语句中插入空白字符遇阻求助

Vim空括号内Space键插入两侧空格的映射问题

需求:配置Space按键映射,当光标处于空括号([]/()/{})内时,在光标两侧插入空格,实现[.] → [ . ](句点代表光标位置)。现有代码中其他功能正常,但循环内的第3条exec语句(Space映射)始终失效,尝试过\"\<Space>\"、\" \"等写法均无效。

原代码:

let bracket_pairs = {'{':'}', '(':')', '[':']'}
  
def InEmptyBrackets(left_brack: string, right_brack: string): bool
   return functions#CharAt(-1) == left_brack && functions#CharAt(0) == right_brack
enddef
  
for [key, value] in items(bracket_pairs)

   " 自动补全闭合括号
   exec "inoremap " . key . " " . key . value . "<Esc>i"

   " 空括号内按Enter自动缩进
   exec "inoremap <expr> <CR> InEmptyBrackets('" . key . "','" . value . "') ? \"\<CR>\<Esc>O\" : \"\<CR>\""

   " 空括号内按Space插入两侧空格(失效的语句)
   exec "inoremap <expr> <Space> InEmptyBrackets('" . key . "','" . value . "') ? \"\<Space>\<Space>\<Esc>i\" : \"\<Space>\""   
                                                         
   " 输入右括号时跳过已存在的闭合括号
   exec "inoremap <expr> " . value . " functions#CharAt(0) == '" . value . "' ? \"\<Esc>la\" : \"" . value . "\""

endfor

配套的CharAt()函数:

def functions#CharAt(distance_from_cursor: number): string
   return getline('.')[col('.') + distance_from_cursor - 1]
enddef

问题根源

循环内多次定义<expr> <Space>和<expr> <CR>映射,每次循环都会覆盖上一次的定义,最终只有最后一对括号([])的判断逻辑生效,其他括号对的场景无法触发映射,表现为Space功能失效。

解决方案

  1. 修改InEmptyBrackets函数,使其无需传参,自动检查所有括号对
  2. 将<Space>和<CR>的<expr>映射移出循环,仅定义一次,避免被覆盖

修改后的完整代码:

let bracket_pairs = {'{':'}', '(':')', '[':']'}

def functions#CharAt(distance_from_cursor: number): string
    return getline('.')[col('.') + distance_from_cursor - 1]
enddef

def InEmptyBrackets(): bool
    let left_char = functions#CharAt(-1)
    let right_char = functions#CharAt(0)
    return has_key(bracket_pairs, left_char) && bracket_pairs[left_char] == right_char
enddef

" 括号自动补全与右括号跳过逻辑保留循环
for [key, value] in items(bracket_pairs)
    " 自动补全闭合括号
    exec "inoremap " . key . " " . key . value . "<Esc>i"

    " 输入右括号时跳过已存在的闭合括号
    exec "inoremap <expr> " . value . " functions#CharAt(0) == '" . value . "' ? \"\<Esc>la\" : \"" . value . "\""
endfor

" 空括号内按Enter自动缩进
inoremap <expr> <CR> InEmptyBrackets() ? "\<CR>\<Esc>O" : "\<CR>"

" 空括号内按Space插入两侧空格
inoremap <expr> <Space> InEmptyBrackets() ? "\<Space>\<Space>\<Esc>i" : "\<Space>"

验证效果

当光标处于()/[]/{}的空括号内时,按下Space键,会自动在光标两侧插入空格,光标停留在中间位置,实现需求效果。

内容的提问来源于stack exchange,提问作者jewbaby91

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:39:15