# HG changeset patch # User Bram Moolenaar # Date 1407341831 -7200 # Node ID 7766142fc7d3e90c2e15a9c606efcd97331edef8 # Parent fe7b9f6ad22665252f36ebf9b9c608bd35534171 updated for version 7.4.396 Problem: When 'clipboard' is "unnamed", :g/pat/d is very slow. (Praful) Solution: Only set the clipboard after the last delete. (Christian Brabandt) diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -5514,7 +5514,15 @@ ex_global(eap) smsg((char_u *)_("Pattern not found: %s"), pat); } else + { +#ifdef FEAT_CLIPBOARD + start_global_changes(); +#endif global_exe(cmd); +#ifdef FEAT_CLIPBOARD + end_global_changes(); +#endif + } ml_clearmarked(); /* clear rest of the marks */ vim_regfree(regmatch.regprog); diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -2464,6 +2464,9 @@ ex_listdo(eap) * great speed improvement. */ save_ei = au_event_disable(",Syntax"); #endif +#ifdef FEAT_CLIPBOARD + start_global_changes(); +#endif if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo @@ -2591,6 +2594,9 @@ ex_listdo(eap) curbuf->b_fname, TRUE, curbuf); } #endif +#ifdef FEAT_CLIPBOARD + end_global_changes(); +#endif } /* @@ -2750,8 +2756,8 @@ source_runtime(name, all) * used. * Returns OK when at least one match found, FAIL otherwise. * - * If "name" is NULL calls callback for each entry in runtimepath. Cookie is - * passed by reference in this case, setting it to NULL indicates that callback + * If "name" is NULL calls callback for each entry in runtimepath. Cookie is + * passed by reference in this case, setting it to NULL indicates that callback * has done its job. */ int diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -11534,6 +11534,10 @@ ex_folddo(eap) { linenr_T lnum; +#ifdef FEAT_CLIPBOARD + start_global_changes(); +#endif + /* First set the marks for all lines closed/open. */ for (lnum = eap->line1; lnum <= eap->line2; ++lnum) if (hasFolding(lnum, NULL, NULL) == (eap->cmdidx == CMD_folddoclosed)) @@ -11542,5 +11546,8 @@ ex_folddo(eap) /* Execute the command on the marked lines. */ global_exe(eap->arg); ml_clearmarked(); /* clear rest of the marks */ -} -#endif +#ifdef FEAT_CLIPBOARD + end_global_changes(); +#endif +} +#endif diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -533,6 +533,8 @@ EXTERN int clip_autoselect_plus INIT(= F EXTERN int clip_autoselectml INIT(= FALSE); EXTERN int clip_html INIT(= FALSE); EXTERN regprog_T *clip_exclude_prog INIT(= NULL); +EXTERN int clip_did_set_selection INIT(= TRUE); +EXTERN int clip_unnamed_saved INIT(= 0); #endif /* diff --git a/src/ops.c b/src/ops.c --- a/src/ops.c +++ b/src/ops.c @@ -1597,9 +1597,15 @@ adjust_clip_reg(rp) { /* If no reg. specified, and "unnamed" or "unnamedplus" is in 'clipboard', * use '*' or '+' reg, respectively. "unnamedplus" prevails. */ - if (*rp == 0 && clip_unnamed != 0) - *rp = ((clip_unnamed & CLIP_UNNAMED_PLUS) && clip_plus.available) + if (*rp == 0 && (clip_unnamed != 0 || clip_unnamed_saved != 0)) + { + if (clip_unnamed != 0) + *rp = ((clip_unnamed & CLIP_UNNAMED_PLUS) && clip_plus.available) ? '+' : '*'; + else + *rp = ((clip_unnamed_saved & CLIP_UNNAMED_PLUS) && clip_plus.available) + ? '+' : '*'; + } if (!clip_star.available && *rp == '*') *rp = 0; if (!clip_plus.available && *rp == '+') @@ -3203,7 +3209,7 @@ op_yank(oap, deleting, mess) if (clip_star.available && (curr == &(y_regs[STAR_REGISTER]) || (!deleting && oap->regname == 0 - && (clip_unnamed & CLIP_UNNAMED)))) + && ((clip_unnamed | clip_unnamed_saved) & CLIP_UNNAMED)))) { if (curr != &(y_regs[STAR_REGISTER])) /* Copy the text from register 0 to the clipboard register. */ @@ -3224,7 +3230,8 @@ op_yank(oap, deleting, mess) if (clip_plus.available && (curr == &(y_regs[PLUS_REGISTER]) || (!deleting && oap->regname == 0 - && (clip_unnamed & CLIP_UNNAMED_PLUS)))) + && ((clip_unnamed | clip_unnamed_saved) & + CLIP_UNNAMED_PLUS)))) { if (curr != &(y_regs[PLUS_REGISTER])) /* Copy the text from register 0 to the clipboard register. */ diff --git a/src/proto/ui.pro b/src/proto/ui.pro --- a/src/proto/ui.pro +++ b/src/proto/ui.pro @@ -14,6 +14,8 @@ void clip_init __ARGS((int can_use)); void clip_update_selection __ARGS((VimClipboard *clip)); void clip_own_selection __ARGS((VimClipboard *cbd)); void clip_lose_selection __ARGS((VimClipboard *cbd)); +void start_global_changes __ARGS((void)); +void end_global_changes __ARGS((void)); void clip_auto_select __ARGS((void)); int clip_isautosel_star __ARGS((void)); int clip_isautosel_plus __ARGS((void)); diff --git a/src/ui.c b/src/ui.c --- a/src/ui.c +++ b/src/ui.c @@ -558,6 +558,51 @@ clip_copy_selection(clip) } /* + * Save and restore clip_unnamed before doing possibly many changes. This + * prevents accessing the clipboard very often which might slow down Vim + * considerably. + */ + +/* + * Save clip_unnamed and reset it. + */ + void +start_global_changes() +{ + clip_unnamed_saved = clip_unnamed; + + if (clip_did_set_selection) + { + clip_unnamed = FALSE; + clip_did_set_selection = FALSE; + } +} + +/* + * Restore clip_unnamed and set the selection when needed. + */ + void +end_global_changes() +{ + if (!clip_did_set_selection) + { + clip_did_set_selection = TRUE; + clip_unnamed = clip_unnamed_saved; + if (clip_unnamed & CLIP_UNNAMED) + { + clip_own_selection(&clip_star); + clip_gen_set_selection(&clip_star); + } + if (clip_unnamed & CLIP_UNNAMED_PLUS) + { + clip_own_selection(&clip_plus); + clip_gen_set_selection(&clip_plus); + } + } + clip_unnamed_saved = FALSE; +} + +/* * Called when Visual mode is ended: update the selection. */ void @@ -1428,6 +1473,15 @@ clip_gen_lose_selection(cbd) clip_gen_set_selection(cbd) VimClipboard *cbd; { + if (!clip_did_set_selection) + { + /* Updating postponed, so that accessing the system clipboard won't + * hang Vim when accessing it many times (e.g. on a :g comand). */ + if (cbd == &clip_plus && (clip_unnamed_saved & CLIP_UNNAMED_PLUS)) + return; + else if (cbd == &clip_star && (clip_unnamed_saved & CLIP_UNNAMED)) + return; + } #ifdef FEAT_XCLIPBOARD # ifdef FEAT_GUI if (gui.in_use) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -742,6 +742,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 396, +/**/ 395, /**/ 394,