1

I have insert-mapped in a script the pattern date<Tab> to insert the current date in the format YYYY-MM-DD.

inoremap <script> <silent> <buffer> date<Tab> <C-R>=strftime("%Y-%m-%d")<CR>

When I start typing the pattern in insert mode, instead of displaying the full pattern before replacing it by the date string only when I press Tab, Vim displays only the last character typed and it is pretty anoying when I don't want to use it. If I'm typing 'date', for instance, this is what Vim displays ('|' is the cursor representation):

  • |d
  • |a
  • |t
  • data|

Also, I have installed the Snipmate vim plugin which makes use of the Tab key to replace snippets by code templates and when I'm typing a snippet, it doesn't behave like I described before. What Snipmate does is to map only the Tab key and when the key is pressed, it gets the previous word and check if it matches one of its snippets.

That said, I will leave two questions and the answer to one of them solves my problem:

  • Is there a way to configure Vim no display the full pattern before changing it to its mappings?

  • Can I have two plugins using the same mapping? Like if I map the Tab key too and whenever the word before the cursor is 'date' my plugins acts and Snipmate acts in the other cases.

freitass
  • 6,542
  • 5
  • 40
  • 44
  • I think your best bet here would be to write a snippet named 'date' that expands to what you want. If I recall correctly, snipmate supports native vimscript inside snippets so this should be very easy to accomplish. The answer to your first question is no. – Randy Morris Jun 18 '11 at 00:32
  • 1
    The best way to achieve what you want is through an abbreviation that auto expands when you type it in insert mode. You can refer [this answer I gave](http://stackoverflow.com/questions/6344750/how-do-i-insert-current-time-into-a-file-using-vim/6344929#6344929) to a question on [how to insert the current time](http://stackoverflow.com/questions/6344750/how-do-i-insert-current-time-into-a-file-using-vim) for details on implementing it. – abcd Jun 18 '11 at 17:56
  • @Randy Morris - The mapping is for a script, so for me it would be fine but I can't assume everyone uses Snipmate. But thanks! – freitass Jun 18 '11 at 20:09

2 Answers2

2

First answer is no.

Second is also no, but it can be emulated:

Generic way is the following (requires frawor):

" plugin/tab.vim
execute frawor#Setup('0.0', {'@/mappings': '0.0'})
" Make sure that mappings were set up
runtime! after/plugin/snipMate.vim

" Get information about already existing mapping
" (it was defined by snipmate)
let s:snipmap=s:_r.map.maparg('<Tab>', 'i', 0)

" Create a new mapping with unique lhs
let s:snipmap.lhs='<SNR>'.s:_sid.'_OldSnipMap'
call s:_r.map.map(s:snipmap)

function s:F.insdate()
    if getline('.')[:(col('.')-1)][-4:] is# 'date'
        return repeat("\<BS>", 4).strftime("%Y-%m-%d")
    else
        " Here is the magic: I have a choice to either use remappable mapping
        " or <C-\><C-o>:call feedkeys()<CR> workaround for nore mapping
        return "\<C-\>\<C-o>:call feedkeys(\"\\<SNR>".s:_sid."_OldSnipMap\")\n"
    endif
endfunction
call s:_f.mapgroup.add('Tab', {'tab': {'lhs': '<Tab>', 'rhs': s:F.insdate, 'mode': 'i'}})

Note that in your example you don't map <Tab>, you map date<Tab> so it does not interfer with snipmate mapping. Above code uses the same approach as IMAP plugin: when last key of {lhs} is pressed, check whether previous keys are in the buffer. If they are remove them and insert {rhs} instead. Thus you can type date<Tab> no matter how slow and it will work.

Note 2: it is the generic way. You can drop frawor dependency and most of the code by simply looking at <Tab> {rhs}:

function s:Insdate()
    if getline('.')[:(col('.')-1)][-4:] is# 'date'
        return repeat("\<BS>", 4).strftime("%Y-%m-%d")
    else
        return "\<C-g>u\<C-r>=TriggerSnippet()\n"
    endif
endfunction
inoremap <Tab> <C-r>=<SID>Insdate()<CR>
ZyX
  • 52,536
  • 7
  • 114
  • 135
0
  • As I know, there seems no such setting to "turn off" the "searching map" status, which vim will eat all the char you type if it is part of some map in keymap matching.

  • Vim only can bind one key to a specific action, so there is no way to make a key do two thing as you may wish. On the other hand, you can configure "snipmate" to use other key to do the "expand" action. And that's should be a usually way when you meet the key conflict problem. Alternatively, you can use "abbreviate" to do something :

    :abbreviate <expr> :date: strftime("%Y-%m-%d")  
    

    But I am sorry for that, the "eating matching" also exists here.

winterTTr
  • 1,739
  • 1
  • 10
  • 30