在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功能失效。
解决方案
- 修改
InEmptyBrackets函数,使其无需传参,自动检查所有括号对 - 将
<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
相关产品推荐
相关产品推荐

