Vim Tips Wiki
(Move categories to tip template)
m (should be 2 choices)
Tag: Visual edit
 
(4 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{review}}
 
 
{{TipImported
 
{{TipImported
 
|id=650
 
|id=650
Line 9: Line 8:
 
|version=6.0
 
|version=6.0
 
|rating=5/5
 
|rating=5/5
|category1=Automated_Text_Insertion
+
|category1=Abbreviations
|category2=
+
|category2=Map
 
}}
 
}}
You can define an abbreviation in such a way that it will ask whether to expand it or not. The trick is to define it as an insert-mode mapping with a special body, not as an abbreviation.
+
You can define an abbreviation in such a way that it will ask whether to expand it or not. The trick is to define it as an expression, then have that expression ask for confirmation:
 
Here is how to define it:
 
 
<pre>
 
function! AskExpand(abbr,expansion)
 
let answer=confirm("Expand '".a:abbr."' [y] ", "&amp;Yes\n&amp;No")
 
if answer==2
 
exec "normal! a".a:abbr
 
else
 
exec "normal! a".a:expansion
 
endif
 
endfunction
 
 
imap ABC &lt;esc&gt;:call AskExpand("ABC","...expansion for ABC ...")&lt;cr&gt;a
 
imap XYZ &lt;esc&gt;:call AskExpand("XYZ","...expansion for XYZ ...")&lt;cr&gt;a
 
</pre>
 
 
==Comments==
 
It would be great if you could have the default prompt Yes or No for each abbreviation. It could be added as a parameter to the AskExpand.
 
 
<pre>
 
"defprompt: 2 =&gt; Yes, 1=&gt; NO
 
function! MyAskExpand(abbr,expansion,defprompt)
 
if a:defprompt==2
 
let answer=confirm("Expand '".a:abbr."' [y] ", "&amp;Yes\n&amp;No")
 
if answer==2
 
exec "normal! a".a:abbr
 
else
 
exec "normal! a".a:expansion
 
endif
 
else
 
let answer=confirm("Expand '".a:abbr."' [n] ", "&amp;No\n&amp;Yes")
 
if answer==1
 
exec "normal! a".a:abbr
 
else
 
exec "normal! a".a:expansion
 
endif
 
endif
 
endfunction
 
 
"imap XYZ &lt;esc&gt;:call myAskExpand("XYZ","...expansion for XYZ ...")&lt;cr&gt;a
 
imap abc &lt;esc&gt;:call MyAskExpand("abc",'buginf("\n:KV:%s ",__FUNCTION__ );',2)&lt;cr&gt;a "default is YES
 
imap xyz &lt;esc&gt;:call MyAskExpand("xyz",'/* VITTAL_DEBUG */',1)&lt;cr&gt;a "default is NO.
 
</pre>
 
 
The above function does not need to be that complex: <tt>confirm()</tt> takes a third argument for the default choice. See my next comment.
 
 
----
 
We can use <tt>:iab</tt> with no problem. The syntax is just slightly different. i.e.:
 
   
 
<pre>
 
<pre>
 
function! s:Ask(abbr,expansion,defprompt)
 
function! s:Ask(abbr,expansion,defprompt)
let answer=confirm("Expand '".a:abbr."'?", "&Yes\n&No", a:defprompt)
+
let answer = confirm("Expand '" . a:abbr . "'?", "&Yes\n&No", a:defprompt)
 
" testing against 1 and not 2, I correctly take care of <abort>
 
" testing against 1 and not 2, I correctly take care of <abort>
return answer==1 ? a:expansion : a:abbr
+
return answer == 1 ? a:expansion : a:abbr
 
endfunction
 
endfunction
   
iab for <c-r>=<sid>Ask('for', "for () {\n}", 1)<cr>
+
iabbrev <expr> for <SID>Ask('for', "for () {\n}", 2)
 
</pre>
 
</pre>
   
  +
==References==
This is the kind of technique I propose in {{script|id=50|text=a Vim library}}, and that by extension, I use in my {{script|id=336|text=C&amp;C++ ftplugin suite}} -- except none of the abbreviations ask question, they are context sensitive.
 
  +
*{{help|:iabbrev}}
  +
*{{help|:map-expression}}
   
 
==Comments==
----
 

Latest revision as of 07:04, 26 December 2019

Tip 650 Printable Monobook Previous Next

created February 4, 2004 · complexity basic · author Yakov Lerner · version 6.0


You can define an abbreviation in such a way that it will ask whether to expand it or not. The trick is to define it as an expression, then have that expression ask for confirmation:

function! s:Ask(abbr,expansion,defprompt)
  let answer = confirm("Expand '" . a:abbr . "'?", "&Yes\n&No", a:defprompt)
  " testing against 1 and not 2, I correctly take care of <abort>
  return answer == 1 ? a:expansion : a:abbr
endfunction

iabbrev <expr> for <SID>Ask('for', "for () {\n}", 2)

References[]

Comments[]