Issue #1 resolved

o and O in insert mode have a pause

Anonymous created an issue

While in insert mode, o and O have a ~1 second pause before the command takes effect. This happens with both the current and development versions.

Comments (8)

  1. dmit

    Confirmed with a Windows build of GVim 7.2.234 and latest VimClojure default and bleeding-edge, with no other plugins and the following .vimrc:

    set nocompatible
    syntax on
    filetype plugin indent on
    

    It appears as if Vim is waiting for a potential key mapping when o is pressed, but :map o shows nothing.

    Interestingly, :nmap o A<CR> works as a temporary fix.

    There is also no pause with the default Lisp mode:

    :set indentexpr=
    :set lisp
    
  2. Meikel Brandmeyer repo owner

    Yes. I have no clue, why this is happening, nor what Vim is waiting for. The function called by o/O and hitting <CR> in insert mode is the same. So I don't really believe it's an issue with the function itself.

    Any hints appreciated!

  3. dmit

    Ok, the difference I'm seeing in GDB is that when indentexpr=GetClojureIndent(), ex_function() sets the msg_scroll variable to TRUE and the conditional in check_for_delay() triggers a one second sleep.

    If indentexpr is unset, then no Vim function is called when o is pressed, the msg_scroll variable stays FALSE and there is no delay.

    Here's the relevant part of the edit() function, which calls check_for_delay():

    /*
     * edit(): Start inserting text.
     *
     * "cmdchar" can be:
     * 'i'	normal insert command
     * 'a'	normal append command
     * 'R'	replace command
     * 'r'	"r<CR>" command: insert one <CR>.  Note: count can be > 1, for redo,
     *	but still only one <CR> is inserted.  The <Esc> is not used for redo.
     * 'g'	"gI" command.
     * 'V'	"gR" command for Virtual Replace mode.
     * 'v'	"gr" command for single character Virtual Replace mode.
     *
     * This function is not called recursively.  For CTRL-O commands, it returns
     * and lets the caller handle the Normal-mode command.
     *
     * Return TRUE if a CTRL-O command caused the return (insert mode pending).
     */
        int
    edit(cmdchar, startln, count)
        int		cmdchar;
        int		startln;	/* if set, insert at start of line */
        long	count;
    {
    
    <...>
    
        /* sleep before redrawing, needed for "CTRL-O :" that results in an
         * error message */
        check_for_delay(TRUE);
    
    <...>
    
    }
    

    So, it appears that the sleep is there because a Vim function is triggered by o and may produce an error message, so we need to wait for that?

    That's pretty much all that I managed to dig up. Perhaps it's time to ask the Vim mailing list.

  4. Meikel Brandmeyer repo owner

    Hmmm... I'm not sure that it is that easy. If it would just depend on indentexpr the following would also trigger the bug, but it doesn't.

    function DelayBug()
      return 5
    endfunction
    
    set indentexpr=DelayBug()
    

    This works fine. So there is either some setting involved or it actually does depend on the function.

  5. Meikel Brandmeyer repo owner

    I went through the indenting code and checked each expression whether it triggers the bug or not. It turned out that there are three places where the bug is triggered:

    • MatchPairs
    • and two calls to vimclojure#Yank

    It seems that there are issues with the poor man's closure approach I used. Eg. vimclojure#Yank yanks text into a register temporarily (I don't know of a function to retrieve the text under the cursor...). The previous register contents are restored afterwards. Similar did MatchPairs for the cursor position. Funnily VimClojureCheckForString does the same without triggering the bug.

    Please try the attached patch. It should be functionally the same, while miraculously not triggering the bug... If there aren't any regression introduced I will commit this as a fix.

  6. Log in to comment