12

我使用映射到我也想在插入模式下工作的正常模式命令。这可以通过添加<C-o>到插入模式映射来完成:

nmap <C-Up> 10<Up>
imap <C-Up> <C-o>10<Up>

但这意味着重复每个映射两次。为避免重复,我尝试“重载”其他一些键,然后将其用于特定于模式的部分:

" F12 selects prefix suitable for current mode
nmap <F12> <Nop>
imap <F12> <C-o>
" single mapping relying on "overloaded" F12 
map <C-Up> <F12>10<Up>

由于某种原因,它不起作用。插入模式下的 F2 仅<F2>作为文本插入。知道出了什么问题以及如何解决吗?如果您可以将解决方案扩展到可视模式,则可以加分。

4

4 回答 4

12

正如 ZyX 已经指出的那样,没有:map适用于所有模式的单一命令,因为它大多没有意义。如果您真的想为所有模式定义映射,请同时使用:mapand :map!; 见:help map-modes

由于您通常只在您的.vimrc.

function! MapBoth(keys, rhs)
    execute 'nmap' a:keys a:rhs
    execute 'imap' a:keys '<C-o>' . a:rhs
endfunction
call MapBoth('<C-Up>', '10<Up>')
于 2012-12-13T07:18:25.003 回答
11

原来的


nnoremap <F2> :w<CR>
inoremap <F2> <Esc>:w<CR>a

map有时不会为所有模式设置它。我不知道确切的原因,所以要确定我喜欢在我的配置文件中明确设置所有映射。我建议你也这样做,因为在某些情况下,由于不同的模式,你会得到意想不到的东西。这就是为什么仔细考虑您为每种特定模式所做的每次重新映射很重要的原因。

此外,支持*noremap命令而不是*map随处可见,因为递归映射是已知的错误来源,尤其是对于初学者。

最后,我不知道你想通过在可视模式下绑定文件写入来实现什么。您是否针对部分缓冲区写入(当您在可视模式下选择某些内容,然后点击此文件写入快捷方式并且只写入选定的文本时)?或者您是否希望在可视模式下写入整个文件,无论您在点击文件写入快捷方式时是否选择了任何内容?提供更多相关信息。就个人而言,无论哪种情况,视觉模式的映射都很奇怪,因为它实际上并没有缩进。将这些东西保持在正常模式下会更好。

更新


由于其他人已经对您的问题给出了详尽的答案,我只是认为如果加上我的 2 美分会有所帮助,但方向略有不同。通过查看您正在尝试做的事情,即在插入模式下映射涉及箭头键的导航功能,我可以推断您对 Vim 非常陌生。您可能已经知道,Vim 背后的理念是在 Vim 中工作时永远不要触摸鼠标——称之为黄金法则

我现在要指出的是,我称之为银法则,它基本上是这样的:

noremap <Up>    <Nop>
noremap <Down>  <Nop>
noremap <Left>  <Nop>
noremap <Right> <Nop>

inoremap <Up>    <Nop>
inoremap <Down>  <Nop>
inoremap <Left>  <Nop>
inoremap <Right> <Nop>

换句话说,防止自己使用箭头键(命令行模式除外)。您的手指应该始终只在字符键区域。Vim 是关于模式的。插入模式不适用于导航 - 它适用于大量输入。当您使用代码或仅使用文本(没关系)时,您大部分时间都在正常模式下 -导航- 浏览文件,寻找下一个着陆的位置以便编辑某些内容,添加一些内容,即做你的下一个输入突发,您切换到插入模式,完成后切换回正常模式以寻找更多的肉 - 像捕食者。:)

那么这到底是怎么回事?我只是想从一开始就引导你走向正确的方向。这样你就可以很快成为中级 Vim 用户——只需几天。为了更好地了解上述所有内容,我建议您绝对应该观看Derek Wyatt 的Vim 新手视频教程,其中他更详细地讨论了所有这些内容,并在截屏视频中展示了这些内容。他还提供了中级高级教程,当您对基础知识感到满意时,您也可以查看这些教程。

祝你快乐vimming!:)

于 2012-12-13T00:37:45.373 回答
7

没有命令来定义所有模式的映射::map正常、操作员挂起和可视模式(真正可视并立即选择)的映射,这在文档中明确说明。为所有模式使用相同的映射没有任何意义,尽管与移动不同的是,保存可以在具有完全相同 rhs 的所有模式中完成:

function s:Save()
    update
    return ''
endfunction
noremap  <expr> <F2> <SID>Save()
noremap! <expr> <F2> <SID>Save()

. noremap!是另一个多模式映射命令,它现在涵盖了插入和命令模式。您不能从<SID>Save()函数(textlock)中移动光标,因此此方法不适用于光标移动命令,但您可以使用变量以避免重复相同的事情两次:

let s:tendownlhs='10j'
execute ' noremap <C-Down>      '.s:tendownlhs
execute 'inoremap <C-Down> <C-o>'.s:tendownlhs

. 现在没有命令模式,因为这很棘手并且可能没用。

于 2012-12-13T04:07:22.367 回答
3

如果映射以正常模式结束是可以的,您可以将for循环与<C-\><C-n>映射结合起来。<C-\><C-n>从任何模式切换到正常模式。

例如,这允许使用 Alt-{h,j,k,l} 从任何模式切换窗格:

for map_command in ['noremap', 'noremap!', 'tnoremap']
  execute map_command . ' <silent> <M-h> <C-\><C-n><C-w>h'
  execute map_command . ' <silent> <M-j> <C-\><C-n><C-w>j'
  execute map_command . ' <silent> <M-k> <C-\><C-n><C-w>k'
  execute map_command . ' <silent> <M-l> <C-\><C-n><C-w>l'
endfor
  • noremap正常、可视和操作员待定模式下的地图
  • noremap!插入和命令模式下的映射
  • tnoremapNeovim 终端模式下的地图
于 2017-04-24T19:06:33.653 回答