Reputation: 3336
I am trying to write a vim function that conditionally changes the behavior of the enter key. I want the enter key to sometimes indent, other times behave "normally". By normally I mean that if a series of cases doesn't apply, act like the function/mapping doesn't exist. The trouble I'm running into is that I'm using <CR>
as my trigger to invoke the function, and thus I'm not sure how to just say "oh, none of these cases apply, execute a <CR>
as if this mapping was never defined."
As an example, consider this in my .vimrc
, which indents the line if it starts with an a
, otherwise triggers a carriage return. (My vimscript is very novice, so this function might not be correct, but I think the idea remains...)
function! SpecialEnter()
let line=getline(".")
if line =~ '\va*'
" at least one space then a valid indentation
normal! >>
else
" just do the regular thing
" echo "in else"
call feedkeys("\<CR>")
endif
endfunction
inoremap <CR> <Esc>:call SpecialEnter()<CR>
This is somewhat simplified from what I'm actually trying to do, but the concept is the same. I'm looking for a way to say "none of my if statements applied, act like this mapping doesn't exist". Is there a way to do this?
Upvotes: 1
Views: 320
Reputation: 196546
You need to give your mapping the <expr>
flag. With this, the right hand side of your mapping is evaluated as an expression.
Here is an example taken from my config where I return different prompts for different commands:
cnoremap <expr> <CR> CCR()
" make list-like commands more intuitive
function! CCR()
let cmdline = getcmdline()
command! -bar Z silent set more|delcommand Z
if cmdline =~ '\v\C^(ls|files|buffers)'
" like :ls but prompts for a buffer command
return "\<CR>:b"
elseif cmdline =~ '\v\C/(#|nu|num|numb|numbe|number)$'
" like :g//# but prompts for a command
return "\<CR>:"
elseif cmdline =~ '\v\C^(dli|il)'
" like :dlist or :ilist but prompts for a count for :djump or :ijump
return "\<CR>:" . cmdline[0] . "j " . split(cmdline, " ")[1] . "\<S-Left>\<Left>"
elseif cmdline =~ '\v\C^(cli|lli)'
" like :clist or :llist but prompts for an error/location number
return "\<CR>:sil " . repeat(cmdline[0], 2) . "\<Space>"
elseif cmdline =~ '\C^old'
" like :oldfiles but prompts for an old file to edit
set nomore
return "\<CR>:Z|e #<"
elseif cmdline =~ '\C^changes'
" like :changes but prompts for a change to jump to
set nomore
return "\<CR>:Z|norm! g;\<S-Left>"
elseif cmdline =~ '\C^ju'
" like :jumps but prompts for a position to jump to
set nomore
return "\<CR>:Z|norm! \<C-o>\<S-Left>"
elseif cmdline =~ '\C^marks'
" like :marks but prompts for a mark to jump to
return "\<CR>:norm! `"
elseif cmdline =~ '\C^undol'
" like :undolist but prompts for a change to undo
return "\<CR>:u "
else
return "\<CR>"
endif
endfunction
Upvotes: 1