在vim中绑定一个键来执行多个表达式映射

Binding a key to execute multiple expression maps in vim

nnoremap <expr> <C-b> ':set bg='.(&bg=='dark' ? "light" : "dark")."<cr>"
nnoremap <expr> <C-b> ':!'.(&bg=='dark' ? "dark" : "light")."<cr>"

两者都可以单独使用,但是当我将键绑定设置为

nnoremap <expr> <C-b> ':set bg='.(&bg=='dark' ? "light" : "dark")."<cr>" \| ':!'.(&bg=='dark' ? "dark" : "light")."<cr>"

只有第一个被执行。如何让按键绑定执行这两个命令?

通过添加 <expr> 修饰符,您告诉 Vim 映射的整个 右侧是一个表达式,但 <bar>中间打断了表达式。

这意味着有条件地执行外部命令的第二个表达式必须以某种方式与第一个表达式融合。在这种特定情况下,有几种方法可以做到这一点,但最简单的方法是将两者连接起来,而不是用 <bar>:

将它们分开
nnoremap <expr> <C-b> ':set bg='.(&bg=='dark' ? "light" : "dark")."<cr>".':!'.(&bg=='dark' ? "dark" : "light")."<cr>"

你也可以有一个三元条件。

但是 one-liner 变得很危险了。这通常是将不可维护的逻辑转变为可读函数开始变得有意义的地方:

function! ToggleBackground()
    let toggles = { "dark": "light", "light": "dark" }
    let &background = toggles[&background]
    call system(toggles[&background])
endfunction
nnoremap <C-b> <Cmd>call ToggleBackground()<CR>