Hi Bram! On Do, 05 Mai 2011, Bram Moolenaar wrote:
> It's simpler if you have it either return zero, KE_CURSORHOLD or > KE_CURSORHOLDR. > > Would we need a separate CursorHoldRepeat and CursorHoldRepeatI? So > that we can separate Normal and Insert mode? Would at least be more > consistent. Attached is an updated patch. Mit freundlichen Grüßen Christian -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php
# HG changeset patch # User Christian Brabandt <c...@256bit.org> # Date 1304661268 -7200 # Node ID ae709f65a5dec832db0c9a55d99f1594b8e14ef3 # Parent 60890b26cb17d892ca8926691800db55b2c465ff imported patch CursorHoldRepeat diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -286,6 +286,11 @@ |FocusLost| Vim lost input focus |CursorHold| the user doesn't press a key for a while |CursorHoldI| the user doesn't press a key for a while in Insert mode +|CursorHoldRepeat| the user doesn't press a key for a while (triggers + continuosly) +|CursorHoldRepeatI| the user doesn't press a key for a while in Insert + mode (triggers + continuosly) |CursorMoved| the cursor was moved in Normal mode |CursorMovedI| the cursor was moved in Insert mode @@ -474,8 +479,9 @@ specified with 'updatetime'. Not re-triggered until the user has pressed a key (i.e. doesn't fire every 'updatetime' ms if you leave Vim to - make some coffee. :) See |CursorHold-example| - for previewing tags. + make some coffee. :) Use the |CursorHoldRepeat| + autocommand if you want it to be retriggered. + See |CursorHold-example| for previewing tags. This event is only triggered in Normal mode. It is not triggered when waiting for a command argument to be typed, or a movement after an @@ -495,6 +501,13 @@ *CursorHoldI* CursorHoldI Just like CursorHold, but in Insert mode. + *CursorHoldRepeat* +CursorHoldRepeat Just like CursorHold, but triggers continuosly. + + *CursorHoldRepeatI* +CursorHoldRepeatI Just like CursorHoldI, but triggers + continuosly + *CursorMoved* CursorMoved After the cursor was moved in Normal mode. Also when the text of the cursor line has been diff --git a/src/edit.c b/src/edit.c --- a/src/edit.c +++ b/src/edit.c @@ -1141,8 +1141,13 @@ #ifdef FEAT_AUTOCMD case K_CURSORHOLD: /* Didn't type something for a while. */ apply_autocmds(EVENT_CURSORHOLDI, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_CURSORHOLDRI, NULL, NULL, FALSE, curbuf); did_cursorhold = TRUE; break; + + case K_CURSORHOLDR: /* Didn't type something for a while. */ + apply_autocmds(EVENT_CURSORHOLDRI, NULL, NULL, FALSE, curbuf); + break; #endif #ifdef FEAT_GUI_W32 @@ -1429,7 +1434,7 @@ #ifdef FEAT_AUTOCMD /* If typed something may trigger CursorHoldI again. */ - if (c != K_CURSORHOLD) + if (c != K_CURSORHOLD && c != K_CURSORHOLDR) did_cursorhold = FALSE; #endif diff --git a/src/fileio.c b/src/fileio.c --- a/src/fileio.c +++ b/src/fileio.c @@ -7650,88 +7650,90 @@ event_T event; /* event number */ } event_names[] = { - {"BufAdd", EVENT_BUFADD}, - {"BufCreate", EVENT_BUFADD}, - {"BufDelete", EVENT_BUFDELETE}, - {"BufEnter", EVENT_BUFENTER}, - {"BufFilePost", EVENT_BUFFILEPOST}, - {"BufFilePre", EVENT_BUFFILEPRE}, - {"BufHidden", EVENT_BUFHIDDEN}, - {"BufLeave", EVENT_BUFLEAVE}, - {"BufNew", EVENT_BUFNEW}, - {"BufNewFile", EVENT_BUFNEWFILE}, - {"BufRead", EVENT_BUFREADPOST}, - {"BufReadCmd", EVENT_BUFREADCMD}, - {"BufReadPost", EVENT_BUFREADPOST}, - {"BufReadPre", EVENT_BUFREADPRE}, - {"BufUnload", EVENT_BUFUNLOAD}, - {"BufWinEnter", EVENT_BUFWINENTER}, - {"BufWinLeave", EVENT_BUFWINLEAVE}, - {"BufWipeout", EVENT_BUFWIPEOUT}, - {"BufWrite", EVENT_BUFWRITEPRE}, - {"BufWritePost", EVENT_BUFWRITEPOST}, - {"BufWritePre", EVENT_BUFWRITEPRE}, - {"BufWriteCmd", EVENT_BUFWRITECMD}, - {"CmdwinEnter", EVENT_CMDWINENTER}, - {"CmdwinLeave", EVENT_CMDWINLEAVE}, - {"ColorScheme", EVENT_COLORSCHEME}, - {"CursorHold", EVENT_CURSORHOLD}, - {"CursorHoldI", EVENT_CURSORHOLDI}, - {"CursorMoved", EVENT_CURSORMOVED}, - {"CursorMovedI", EVENT_CURSORMOVEDI}, - {"EncodingChanged", EVENT_ENCODINGCHANGED}, - {"FileEncoding", EVENT_ENCODINGCHANGED}, - {"FileAppendPost", EVENT_FILEAPPENDPOST}, - {"FileAppendPre", EVENT_FILEAPPENDPRE}, - {"FileAppendCmd", EVENT_FILEAPPENDCMD}, - {"FileChangedShell",EVENT_FILECHANGEDSHELL}, - {"FileChangedShellPost",EVENT_FILECHANGEDSHELLPOST}, - {"FileChangedRO", EVENT_FILECHANGEDRO}, - {"FileReadPost", EVENT_FILEREADPOST}, - {"FileReadPre", EVENT_FILEREADPRE}, - {"FileReadCmd", EVENT_FILEREADCMD}, - {"FileType", EVENT_FILETYPE}, - {"FileWritePost", EVENT_FILEWRITEPOST}, - {"FileWritePre", EVENT_FILEWRITEPRE}, - {"FileWriteCmd", EVENT_FILEWRITECMD}, - {"FilterReadPost", EVENT_FILTERREADPOST}, - {"FilterReadPre", EVENT_FILTERREADPRE}, - {"FilterWritePost", EVENT_FILTERWRITEPOST}, - {"FilterWritePre", EVENT_FILTERWRITEPRE}, - {"FocusGained", EVENT_FOCUSGAINED}, - {"FocusLost", EVENT_FOCUSLOST}, - {"FuncUndefined", EVENT_FUNCUNDEFINED}, - {"GUIEnter", EVENT_GUIENTER}, - {"GUIFailed", EVENT_GUIFAILED}, - {"InsertChange", EVENT_INSERTCHANGE}, - {"InsertEnter", EVENT_INSERTENTER}, - {"InsertLeave", EVENT_INSERTLEAVE}, - {"MenuPopup", EVENT_MENUPOPUP}, - {"QuickFixCmdPost", EVENT_QUICKFIXCMDPOST}, - {"QuickFixCmdPre", EVENT_QUICKFIXCMDPRE}, - {"RemoteReply", EVENT_REMOTEREPLY}, - {"SessionLoadPost", EVENT_SESSIONLOADPOST}, - {"ShellCmdPost", EVENT_SHELLCMDPOST}, - {"ShellFilterPost", EVENT_SHELLFILTERPOST}, - {"SourcePre", EVENT_SOURCEPRE}, - {"SourceCmd", EVENT_SOURCECMD}, - {"SpellFileMissing",EVENT_SPELLFILEMISSING}, - {"StdinReadPost", EVENT_STDINREADPOST}, - {"StdinReadPre", EVENT_STDINREADPRE}, - {"SwapExists", EVENT_SWAPEXISTS}, - {"Syntax", EVENT_SYNTAX}, - {"TabEnter", EVENT_TABENTER}, - {"TabLeave", EVENT_TABLEAVE}, - {"TermChanged", EVENT_TERMCHANGED}, - {"TermResponse", EVENT_TERMRESPONSE}, - {"User", EVENT_USER}, - {"VimEnter", EVENT_VIMENTER}, - {"VimLeave", EVENT_VIMLEAVE}, - {"VimLeavePre", EVENT_VIMLEAVEPRE}, - {"WinEnter", EVENT_WINENTER}, - {"WinLeave", EVENT_WINLEAVE}, - {"VimResized", EVENT_VIMRESIZED}, - {NULL, (event_T)0} + {"BufAdd", EVENT_BUFADD}, + {"BufCreate", EVENT_BUFADD}, + {"BufDelete", EVENT_BUFDELETE}, + {"BufEnter", EVENT_BUFENTER}, + {"BufFilePost", EVENT_BUFFILEPOST}, + {"BufFilePre", EVENT_BUFFILEPRE}, + {"BufHidden", EVENT_BUFHIDDEN}, + {"BufLeave", EVENT_BUFLEAVE}, + {"BufNew", EVENT_BUFNEW}, + {"BufNewFile", EVENT_BUFNEWFILE}, + {"BufRead", EVENT_BUFREADPOST}, + {"BufReadCmd", EVENT_BUFREADCMD}, + {"BufReadPost", EVENT_BUFREADPOST}, + {"BufReadPre", EVENT_BUFREADPRE}, + {"BufUnload", EVENT_BUFUNLOAD}, + {"BufWinEnter", EVENT_BUFWINENTER}, + {"BufWinLeave", EVENT_BUFWINLEAVE}, + {"BufWipeout", EVENT_BUFWIPEOUT}, + {"BufWrite", EVENT_BUFWRITEPRE}, + {"BufWritePost", EVENT_BUFWRITEPOST}, + {"BufWritePre", EVENT_BUFWRITEPRE}, + {"BufWriteCmd", EVENT_BUFWRITECMD}, + {"CmdwinEnter", EVENT_CMDWINENTER}, + {"CmdwinLeave", EVENT_CMDWINLEAVE}, + {"ColorScheme", EVENT_COLORSCHEME}, + {"CursorHold", EVENT_CURSORHOLD}, + {"CursorHoldI", EVENT_CURSORHOLDI}, + {"CursorHoldRepeat", EVENT_CURSORHOLDR}, + {"CursorHoldRepeatI", EVENT_CURSORHOLDRI}, + {"CursorMoved", EVENT_CURSORMOVED}, + {"CursorMovedI", EVENT_CURSORMOVEDI}, + {"EncodingChanged", EVENT_ENCODINGCHANGED}, + {"FileEncoding", EVENT_ENCODINGCHANGED}, + {"FileAppendPost", EVENT_FILEAPPENDPOST}, + {"FileAppendPre", EVENT_FILEAPPENDPRE}, + {"FileAppendCmd", EVENT_FILEAPPENDCMD}, + {"FileChangedShell", EVENT_FILECHANGEDSHELL}, + {"FileChangedShellPost", EVENT_FILECHANGEDSHELLPOST}, + {"FileChangedRO", EVENT_FILECHANGEDRO}, + {"FileReadPost", EVENT_FILEREADPOST}, + {"FileReadPre", EVENT_FILEREADPRE}, + {"FileReadCmd", EVENT_FILEREADCMD}, + {"FileType", EVENT_FILETYPE}, + {"FileWritePost", EVENT_FILEWRITEPOST}, + {"FileWritePre", EVENT_FILEWRITEPRE}, + {"FileWriteCmd", EVENT_FILEWRITECMD}, + {"FilterReadPost", EVENT_FILTERREADPOST}, + {"FilterReadPre", EVENT_FILTERREADPRE}, + {"FilterWritePost", EVENT_FILTERWRITEPOST}, + {"FilterWritePre", EVENT_FILTERWRITEPRE}, + {"FocusGained", EVENT_FOCUSGAINED}, + {"FocusLost", EVENT_FOCUSLOST}, + {"FuncUndefined", EVENT_FUNCUNDEFINED}, + {"GUIEnter", EVENT_GUIENTER}, + {"GUIFailed", EVENT_GUIFAILED}, + {"InsertChange", EVENT_INSERTCHANGE}, + {"InsertEnter", EVENT_INSERTENTER}, + {"InsertLeave", EVENT_INSERTLEAVE}, + {"MenuPopup", EVENT_MENUPOPUP}, + {"QuickFixCmdPost", EVENT_QUICKFIXCMDPOST}, + {"QuickFixCmdPre", EVENT_QUICKFIXCMDPRE}, + {"RemoteReply", EVENT_REMOTEREPLY}, + {"SessionLoadPost", EVENT_SESSIONLOADPOST}, + {"ShellCmdPost", EVENT_SHELLCMDPOST}, + {"ShellFilterPost", EVENT_SHELLFILTERPOST}, + {"SourcePre", EVENT_SOURCEPRE}, + {"SourceCmd", EVENT_SOURCECMD}, + {"SpellFileMissing", EVENT_SPELLFILEMISSING}, + {"StdinReadPost", EVENT_STDINREADPOST}, + {"StdinReadPre", EVENT_STDINREADPRE}, + {"SwapExists", EVENT_SWAPEXISTS}, + {"Syntax", EVENT_SYNTAX}, + {"TabEnter", EVENT_TABENTER}, + {"TabLeave", EVENT_TABLEAVE}, + {"TermChanged", EVENT_TERMCHANGED}, + {"TermResponse", EVENT_TERMRESPONSE}, + {"User", EVENT_USER}, + {"VimEnter", EVENT_VIMENTER}, + {"VimLeave", EVENT_VIMLEAVE}, + {"VimLeavePre", EVENT_VIMLEAVEPRE}, + {"WinEnter", EVENT_WINENTER}, + {"WinLeave", EVENT_WINLEAVE}, + {"VimResized", EVENT_VIMRESIZED}, + {NULL, (event_T)0} }; static AutoPat *first_autopat[NUM_EVENTS] = @@ -9079,25 +9081,44 @@ ? EVENT_CURSORHOLD : EVENT_CURSORHOLDI)] != NULL); } + int +has_cursorholdr() +{ + return (first_autopat[(int)(get_real_state() == NORMAL_BUSY + ? EVENT_CURSORHOLDR : EVENT_CURSORHOLDRI)] != NULL); +} + + /* - * Return TRUE if the CursorHold event can be triggered. + * Return 0 if no CursorHold event can be triggered + * Return KE_CURSORHOLD if the CursorHold event can be triggered. + * Return KE_CURSORHOLDR if the CursorHoldR event can be triggered. */ int trigger_cursorhold() { int state; + state = get_real_state(); if (!did_cursorhold && has_cursorhold() && !Recording #ifdef FEAT_INS_EXPAND && !ins_compl_active() #endif ) { - state = get_real_state(); if (state == NORMAL_BUSY || (state & INSERT) != 0) - return TRUE; - } - return FALSE; + return KE_CURSORHOLD; + } + else if (has_cursorholdr() && !Recording +#ifdef FEAT_INS_EXPAND + && !ins_compl_active() +#endif + ) + { + if ( state == NORMAL_BUSY || (state & INSERT) != 0) + return KE_CURSORHOLDR; + } + return 0; } /* diff --git a/src/getchar.c b/src/getchar.c --- a/src/getchar.c +++ b/src/getchar.c @@ -3066,7 +3066,8 @@ if (p[0] == NUL || (p[0] == K_SPECIAL && !script #ifdef FEAT_AUTOCMD /* timeout may generate K_CURSORHOLD */ - && (i < 2 || p[1] != KS_EXTRA || p[2] != (int)KE_CURSORHOLD) + && (i < 2 || p[1] != KS_EXTRA || + (p[2] != (int)KE_CURSORHOLD && p[2] != (int) KE_CURSORHOLDR)) #endif #if defined(WIN3264) && !defined(FEAT_GUI) /* Win32 console passes modifiers */ diff --git a/src/gui.c b/src/gui.c --- a/src/gui.c +++ b/src/gui.c @@ -2718,14 +2718,14 @@ if (gui_mch_wait_for_chars(p_ut) == OK) retval = OK; #ifdef FEAT_AUTOCMD - else if (trigger_cursorhold()) + else if (trigger_cursorhold() != 0) { char_u buf[3]; /* Put K_CURSORHOLD in the input buffer. */ buf[0] = CSI; buf[1] = KS_EXTRA; - buf[2] = (int)KE_CURSORHOLD; + buf[2] = (int)trigger_cursorhold(); add_to_input_buf(buf, 3); retval = OK; diff --git a/src/keymap.h b/src/keymap.h --- a/src/keymap.h +++ b/src/keymap.h @@ -258,6 +258,7 @@ , KE_DROP /* DnD data is available */ , KE_CURSORHOLD /* CursorHold event */ + , KE_CURSORHOLDR /* CursorHoldR event */ , KE_NOP /* doesn't do something */ , KE_FOCUSGAINED /* focus gained */ , KE_FOCUSLOST /* focus lost */ @@ -458,6 +459,7 @@ #define K_FOCUSLOST TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST) #define K_CURSORHOLD TERMCAP2KEY(KS_EXTRA, KE_CURSORHOLD) +#define K_CURSORHOLDR TERMCAP2KEY(KS_EXTRA, KE_CURSORHOLDR) /* Bits for modifier mask */ /* 0x01 cannot be used, because the modifier must be 0x02 or higher */ diff --git a/src/normal.c b/src/normal.c --- a/src/normal.c +++ b/src/normal.c @@ -184,6 +184,7 @@ #endif #ifdef FEAT_AUTOCMD static void nv_cursorhold __ARGS((cmdarg_T *cap)); +static void nv_cursorholdr __ARGS((cmdarg_T *cap)); #endif static char *e_noident = N_("E349: No identifier under cursor"); @@ -452,6 +453,7 @@ #endif #ifdef FEAT_AUTOCMD {K_CURSORHOLD, nv_cursorhold, NV_KEEPREG, 0}, + {K_CURSORHOLDR, nv_cursorholdr, NV_KEEPREG, 0}, #endif }; @@ -779,7 +781,7 @@ } #ifdef FEAT_AUTOCMD - if (c == K_CURSORHOLD) + if (c == K_CURSORHOLD || c == K_CURSORHOLDR) { /* Save the count values so that ca.opcount and ca.count0 are exactly * the same when coming back here after handling K_CURSORHOLD. */ @@ -1318,7 +1320,8 @@ #ifdef FEAT_CMDL_INFO if (oap->op_type == OP_NOP && oap->regname == 0 # ifdef FEAT_AUTOCMD - && ca.cmdchar != K_CURSORHOLD + && ca.cmdchar != K_CURSORHOLD + && ca.cmdchar != K_CURSORHOLDR # endif ) clear_showcmd(); @@ -3888,7 +3891,7 @@ K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE, K_MOUSEDOWN, K_MOUSEUP, K_MOUSELEFT, K_MOUSERIGHT, K_X1MOUSE, K_X1DRAG, K_X1RELEASE, K_X2MOUSE, K_X2DRAG, K_X2RELEASE, - K_CURSORHOLD, + K_CURSORHOLD, K_CURSORHOLDR, 0 }; #endif @@ -9435,7 +9438,17 @@ cmdarg_T *cap; { apply_autocmds(EVENT_CURSORHOLD, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_CURSORHOLDR, NULL, NULL, FALSE, curbuf); did_cursorhold = TRUE; cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */ } -#endif + + static void +nv_cursorholdr(cap) + cmdarg_T *cap; +{ + apply_autocmds(EVENT_CURSORHOLDR, NULL, NULL, FALSE, curbuf); + did_cursorhold = TRUE; + cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */ +} +#endif diff --git a/src/os_amiga.c b/src/os_amiga.c --- a/src/os_amiga.c +++ b/src/os_amiga.c @@ -150,11 +150,11 @@ if (WaitForChar(raw_in, p_ut * 1000L) == 0) { #ifdef FEAT_AUTOCMD - if (trigger_cursorhold() && maxlen >= 3) + if (trigger_cursorhold() != 0 && maxlen >= 3) { buf[0] = K_SPECIAL; buf[1] = KS_EXTRA; - buf[2] = (int)KE_CURSORHOLD; + buf[2] = (int)trigger_cursorhold(); return 3; } #endif diff --git a/src/os_msdos.c b/src/os_msdos.c --- a/src/os_msdos.c +++ b/src/os_msdos.c @@ -1033,11 +1033,11 @@ if (WaitForChar(p_ut) == 0) { #ifdef FEAT_AUTOCMD - if (trigger_cursorhold() && maxlen >= 3) + if (trigger_cursorhold() != 0 && maxlen >= 3) { buf[0] = K_SPECIAL; buf[1] = KS_EXTRA; - buf[2] = (int)KE_CURSORHOLD; + buf[2] = (int)trigger_cursorhold(); return 3; } #endif diff --git a/src/os_unix.c b/src/os_unix.c --- a/src/os_unix.c +++ b/src/os_unix.c @@ -399,12 +399,12 @@ if (WaitForChar(p_ut) == 0) { #ifdef FEAT_AUTOCMD - if (trigger_cursorhold() && maxlen >= 3 + if (trigger_cursorhold() != 0 && maxlen >= 3 && !typebuf_changed(tb_change_cnt)) { buf[0] = K_SPECIAL; buf[1] = KS_EXTRA; - buf[2] = (int)KE_CURSORHOLD; + buf[2] = (int)trigger_cursorhold(); return 3; } #endif diff --git a/src/os_win32.c b/src/os_win32.c --- a/src/os_win32.c +++ b/src/os_win32.c @@ -1426,11 +1426,11 @@ if (!WaitForChar(p_ut)) { #ifdef FEAT_AUTOCMD - if (trigger_cursorhold() && maxlen >= 3) + if (trigger_cursorhold() != 0 && maxlen >= 3) { buf[0] = K_SPECIAL; buf[1] = KS_EXTRA; - buf[2] = (int)KE_CURSORHOLD; + buf[2] = (int)trigger_cursorhold(); return 3; } #endif diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro --- a/src/proto/fileio.pro +++ b/src/proto/fileio.pro @@ -40,6 +40,7 @@ int apply_autocmds __ARGS((event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf)); int apply_autocmds_retval __ARGS((event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, int *retval)); int has_cursorhold __ARGS((void)); +int has_cursorholdr __ARGS((void)); int trigger_cursorhold __ARGS((void)); int has_cursormoved __ARGS((void)); int has_cursormovedI __ARGS((void)); diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -1283,6 +1283,8 @@ EVENT_ENCODINGCHANGED, /* after changing the 'encoding' option */ EVENT_CURSORHOLD, /* cursor in same position for a while */ EVENT_CURSORHOLDI, /* idem, in Insert mode */ + EVENT_CURSORHOLDR, /* idem, repeatedly */ + EVENT_CURSORHOLDRI, /* idem, in Insert mode repeatedly */ EVENT_FUNCUNDEFINED, /* if calling a function which doesn't exist */ EVENT_REMOTEREPLY, /* upon string reception from a remote vim */ EVENT_SWAPEXISTS, /* found existing swap file */