Vim:多种模式的重载映射

时间:2012-12-13 00:09:20

标签: vim

我使用映射到普通模式命令,我也想在插入模式下工作。这可以通过将<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 个答案:

答案 0 :(得分:9)

正如ZyX已经指出的那样,所有模式都没有单:map命令,因为它几乎没有意义。如果您确实要为所有模式定义映射,请同时使用:map: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>')

答案 1 :(得分:8)

<强>原始


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 Novice Video Tutorials,在那里他会更详细地讨论所有这些内容,并在截屏视频中展示它。他还有IntermediateAdvanced教程,当您对基础知识感到满意时,您也会看到这些教程。

祝你好运! :)

答案 2 :(得分:5)

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

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

noremap!是另一种多模式映射命令,它现在涵盖了插入和命令模式。您无法将光标从<SID>Save()函数(文本锁定)移动,因此此方法不适用于光标移动命令,但您可以使用变量以便不重复相同的操作两次:

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

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

答案 3 :(得分:2)

如果映射在正常模式下结束是可以的,则可以将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!以插入和命令模式映射
  • tnoremap地图在Neovim的终端模式