Problem with CursorMoved AutoCommand when Editing Files on a Remote WIndows Share

174 views
Skip to first unread message

David Kotchan

unread,
Sep 14, 2008, 5:45:29 PM9/14/08
to vim...@googlegroups.com
Hello fellow Vimmers

I've discovered a problem with Vim 7.2 when using the CursorMoved
autocommand under Windows. The problem is only evident when editing
files on a Windows share, rather than editing a file on the local
machine. (Presumably the same issue is occurring even when editing on
the local machine, but is only obvious when editing files on a Windows
share.)

The problem does not occur under Vim 7.1, so I conclude something has
changed with how CursorMoved events are handled in Vim 7.2.

Repro steps: I use the clever 'halfmove.vim' script created by Andy
Spencer, which uses the CursorMoved autocommand on each keystroke. My
problem can be easily repro'd: with the halfmove script in the \plugin
folder, simply use Vim 7.2 to edit a file on some remote share (eg. 'vim
\\FRED\barney.txt', barney.txt being some file on a remote machine named
FRED). Then hold down the 'j' or 'k' keys to scroll the text window. The
window scrolls very slowly and with fits and starts. In worst cases
scrolling is so slow that barney.txt cannot usefully be edited. Network
activity is also very high during the scrolling.

Deleting the 'halfmove.vim' script from the \plugin folder, or
(alternately) commenting out the CursorMoved autocommand from that
script, cures the problem. Vim 7.2 then becomes as speedy as Vim 7.1.

Since the issue does not occur for Vim 7.1, I'm sticking with Vim 7.1
for now (because I really like the functionality offered by the
halfmove.vim script, and I have to edit quite a few files on remote
shares). But evidently something significant has changed in how Vim 7.2
handles the CursorMoved event.

Experiments show that the slowdown occurs even when CursorMoved is set
up to call an empty (no-op) function; that is, it's not the work being
done in the function that causes the slowdown, but the fact that
CursorMoved is calling a Vim function at all.

I've experimented with several of the source code files for 7.2 in an
attempt to figure out why/where the issue is occurring, but so far
haven't found a solution. Can anyone offer any insight? What changes
were made in 7.2's handling of CursorMoved that might be causing this
problem?

I've seen the issue under both Vista and WinXP. I'm using the console
mode version of Vim 7.2.

Any help appreciated.

Thanks
--David Kotchan


John Beckett

unread,
Sep 14, 2008, 11:17:11 PM9/14/08
to vim...@googlegroups.com
David Kotchan wrote:
> I've discovered a problem with Vim 7.2 when using the
> CursorMoved autocommand under Windows. The problem is only
> evident when editing files on a Windows share

Perhaps this recent thread is relevant?
http://groups.google.com/group/vim_use/browse_thread/thread/a1bb61d035b4005/5dbb99b6
fdcfa638?lnk=gst&q=cursormoved+slow#5dbb99b6fdcfa638

The thread won't solve your problem, but it would be interesting to know if it's the
same.

John

Bram Moolenaar

unread,
Sep 15, 2008, 2:22:11 PM9/15/08
to David Kotchan, vim...@googlegroups.com

David Kotchan wrote:

What is the autocommand being executed? Can you reproduce it with a
very simple script?

I guess it's caused by the file name being expanded into a full path.
I need to know what you are doing to see if it can be avoided.

--
hundred-and-one symptoms of being an internet addict:
58. You turn on your computer and turn off your wife.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

David Kotchan

unread,
Sep 15, 2008, 10:03:53 PM9/15/08
to vim...@googlegroups.com
Here is a simple script that reproduces the problem. In fact, this *is*
the CursorMoved autocommand used in the script I referred to above
(halfmove.vim):

--------------------
function HM_Inc()
if (!exists("s:reset"))
let s:reset = 1
endif
let s:reset += 1
endfunction

autocmd CursorMoved * call HM_Inc()
--------------------

Thanks
--David


David Kotchan

unread,
Sep 15, 2008, 10:05:25 PM9/15/08
to vim...@googlegroups.com
Thanks John. That's an interesting link. I'm not sure if it's the same
problem or not; it does seem to share some of the same characteristics.
I'll follow on with that thread and see what's up.

Thanks
--David

Bram Moolenaar

unread,
Sep 16, 2008, 3:08:41 PM9/16/08
to David Kotchan, vim...@googlegroups.com

David Kotchan wrote:

OK. What is important here is the "*" pattern. I have an idea to skip
all the pattern matching and file name expansion stuff if all the
patterns are "*". They will all match anyway.

--
hundred-and-one symptoms of being an internet addict:

62. If your doorbell rings, you think that new mail has arrived. And then
you're disappointed that it's only someone at the door.

Bram Moolenaar

unread,
Sep 16, 2008, 3:34:17 PM9/16/08
to David Kotchan, vim...@googlegroups.com

David Kotchan wrote:

> Here is a simple script that reproduces the problem. In fact, this *is*
> the CursorMoved autocommand used in the script I referred to above
> (halfmove.vim):
>
> --------------------
> function HM_Inc()
> if (!exists("s:reset"))
> let s:reset = 1
> endif
> let s:reset += 1
> endfunction
>
> autocmd CursorMoved * call HM_Inc()
> --------------------

The patch below should avoid expanding the file name for this kind of
autocommand. This also works for the matchparen plugin, which is
enabled by default.

Let me know if this solves the delay for you.

*** ../vim-7.2.018/src/ex_docmd.c Sat Jul 26 16:04:39 2008
--- src/ex_docmd.c Mon Sep 15 20:04:53 2008
***************
*** 9541,9546 ****
--- 9569,9583 ----
#ifdef FEAT_AUTOCMD
case SPEC_AFILE: /* file name for autocommand */
result = autocmd_fname;
+ if (result != NULL && !autocmd_fname_full)
+ {
+ /* Still need to turn the fname into a full path. It is
+ * postponed to avoid a delay when <afile> is not used. */
+ autocmd_fname_full = TRUE;
+ result = FullName_save(autocmd_fname, FALSE);
+ vim_free(autocmd_fname);
+ autocmd_fname = result;
+ }
if (result == NULL)
{
*errormsg = (char_u *)_("E495: no autocommand file name to substitute for \"<afile>\"");
*** ../vim-7.2.018/src/fileio.c Wed Aug 6 18:43:07 2008
--- src/fileio.c Tue Sep 16 21:24:26 2008
***************
*** 8523,8528 ****
--- 8523,8529 ----
char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
char_u *save_autocmd_fname;
+ int save_autocmd_fname_full;
int save_autocmd_bufnr;
char_u *save_autocmd_match;
int save_autocmd_busy;
***************
*** 8601,8606 ****
--- 8602,8608 ----
* Save the autocmd_* variables and info about the current buffer.
*/
save_autocmd_fname = autocmd_fname;
+ save_autocmd_fname_full = autocmd_fname_full;
save_autocmd_bufnr = autocmd_bufnr;
save_autocmd_match = autocmd_match;
save_autocmd_busy = autocmd_busy;
***************
*** 8618,8631 ****
if (fname != NULL && *fname != NUL)
autocmd_fname = fname;
else if (buf != NULL)
! autocmd_fname = buf->b_fname;
else
autocmd_fname = NULL;
}
else
autocmd_fname = fname_io;
if (autocmd_fname != NULL)
! autocmd_fname = FullName_save(autocmd_fname, FALSE);

/*
* Set the buffer number to be used for <abuf>.
--- 8620,8634 ----
if (fname != NULL && *fname != NUL)
autocmd_fname = fname;
else if (buf != NULL)
! autocmd_fname = buf->b_ffname;
else
autocmd_fname = NULL;
}
else
autocmd_fname = fname_io;
if (autocmd_fname != NULL)
! autocmd_fname = vim_strsave(autocmd_fname);
! autocmd_fname_full = FALSE; /* call FullName_save() later */

/*
* Set the buffer number to be used for <abuf>.
***************
*** 8810,8815 ****
--- 8813,8819 ----
sourcing_lnum = save_sourcing_lnum;
vim_free(autocmd_fname);
autocmd_fname = save_autocmd_fname;
+ autocmd_fname_full = save_autocmd_fname_full;
autocmd_bufnr = save_autocmd_bufnr;
autocmd_match = save_autocmd_match;
#ifdef FEAT_EVAL
*** ../vim-7.2.018/src/globals.h Sat Jul 26 16:04:49 2008
--- src/globals.h Mon Sep 15 19:59:28 2008
***************
*** 1022,1027 ****
--- 1022,1028 ----
#endif
#ifdef FEAT_AUTOCMD
EXTERN char_u *autocmd_fname INIT(= NULL); /* fname for <afile> on cmdline */
+ EXTERN int autocmd_fname_full; /* autocmd_fname is full path */
EXTERN int autocmd_bufnr INIT(= 0); /* fnum for <abuf> on cmdline */
EXTERN char_u *autocmd_match INIT(= NULL); /* name for <amatch> on cmdline */
EXTERN int did_cursorhold INIT(= FALSE); /* set when CursorHold t'gerd */


--
hundred-and-one symptoms of being an internet addict:

67. Your hard drive crashes. You haven't logged in for two hours. You start
to twitch. You pick up the phone and manually dial your ISP's access
number. You try to hum to communicate with the modem. You succeed.

David Kotchan

unread,
Sep 17, 2008, 12:01:53 AM9/17/08
to vim...@googlegroups.com, Bram Moolenaar
This patch works beautifully! Problem solved. Thanks very much, Bram.

Perhaps this patch also solves the problem mentioned by John Beckett:

http://groups.google.com/group/vim_use/browse_thread/thread/a1bb61d035b4005/5dbb99b6
fdcfa638?lnk=gst&q=cursormoved+slow#5dbb99b6fdcfa638

Thanks again!
--David

Reply all
Reply to author
Forward
0 new messages