1

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?

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.