(previous version caused glitches because the cursor indiscriminately moved right then left) |
(fix a typo) |
||
Line 14: | Line 14: | ||
__TOC__ |
__TOC__ |
||
==Faking a timer== |
==Faking a timer== |
||
− | Since there is no timer function in Vim, a trick is needed: use two autocommands that invoke each another. In the following, the <tt> |
+ | Since there is no timer function in Vim, a trick is needed: use two autocommands that invoke each another. In the following, the <tt>CursorHold</tt> and <tt>CursorMoved</tt> events are used; each cancels the action performed by the other. The period can be set via the <tt>updatetime</tt> option (abbreviated to <tt>ut</tt>). |
<pre> |
<pre> |
||
let moveflag = 0 |
let moveflag = 0 |
Revision as of 01:49, 30 October 2009
It may be helpful to run a commmand periodically in the background. This can be used, for example, to write an auto-updating clock in Vim, or to check for user input via an input loop, such as in a game. In one application, Vim was used as a front end for a media player, where the song information had to be updated and other actions taken when a song finished.
Faking a timer
Since there is no timer function in Vim, a trick is needed: use two autocommands that invoke each another. In the following, the CursorHold and CursorMoved events are used; each cancels the action performed by the other. The period can be set via the updatetime option (abbreviated to ut).
let moveflag = 0 au CursorHold * let moveflag=1 | let previnmiddle=0 | let prevjustabovemid=0 | let middleline=(line("w0")+line("w$"))/2 | if line(".")==middleline | let previnmiddle=1 | endif | if line(".")+1==middleline | let prevjustabovemid=1 | endif | if line(".")<middleline | exe "normal j" | else | exe "normal k" | endif au CursorMoved * if moveflag==1 | let middleline=(line("w0")+line("w$"))/2 | if previnmiddle==1 | exe "normal j" | else | if prevjustabovemid==1 | exe "normal k" | else | if line(".")<middleline | exe "normal k" | else | exe "normal j" | endif | endif | endif | let moveflag=0 | endif set noswapfile set ut=3000
Here, the autocommand CursorMoved event distinguishes user movements from autocommand movements via the moveflag variable. This loop increments and displays k every 3 seconds while the cursor is idle.
The noswapfile option is set so that Vim isn't writing to a swap file every 3 seconds, if the action happens to update the file.
All the code is there simply to make sure the action caused to trigger off the auto commands returns things to exactly the same place where they were before. It's nasty but it works. It's done by moving the cursor up then down, or vice versa, or vice versa again if the cursor is near the middle of the screen.