A new patch fixes the issues: now it checks if b_mod_set is already set and do 
not overwrite b_mod_top and b_mod_bot in this case.

среда, 28 мая 2014 г., 10:17:08 UTC+4 пользователь Alexey Radkov написал:
> Unfortunately this patch works badly when entering new lines before matched 
> paren: consequent new lines show artifacts and matched pair does not change 
> if cursor moved.
> 
> 
> 
> среда, 28 мая 2014 г., 1:40:26 UTC+4 пользователь Alexey Radkov написал:
> 
> > Hi all.
> 
> > 
> 
> > My home computer is
> 
> > 
> 
> > Linux 3.14.4-200.fc20.x86_64 x86_64 x86_64 x86_64 GNU/Linux
> 
> > 
> 
> > running on
> 
> > 
> 
> > AMD Athlon(tm) 64 X2 Dual Core Processor 5200+
> 
> > 
> 
> > Relatively old. And matchparen (I use matchparen++ but they do not differ a 
> > lot) may perform extremely slow in some cases. I found that most slow call 
> > in the plugin is 3match and tried to increase its performance in the 
> > attached patch.
> 
> > 
> 
> > The idea of the patch:
> 
> > 
> 
> > Functions match_add() and match_delete() redraw whole screen passing flag 
> > SOME_VALID to redraw_later(). However matchparen does not require that all 
> > screen must be redrawn: the positions of matching pairs are well known and 
> > they are passed in the pattern regexp like \(\%24l\%31c\)\|\(\%28l\%36c\), 
> > so they can be easily retrieved in the match_add()/_delete(). Another fact 
> > that hints that we are dealing with matchparen is id 3 (:3match is mostly 
> > solely used for matchparen as the vim doc says). Now we can calculate 
> > boundaries for redrawing area, set wp->w_buffer->b_mod_set and 
> > corresponding top and bottom lines numbers and finally pass VALID to 
> > redraw_later() and it should redraw only between the top and the bottom 
> > lines.
> 
> > 
> 
> > The patch works best for specific cases:
> 
> > 
> 
> > when matching pairs are located on the same line or close lines and 
> > terminal area is big enough (this shows best difference due to small redraw 
> > area to the whole terminal area large relation value).
> 
> > 
> 
> > I am not sure if this patch is clean (especially when using 
> > wp->w_buffer->b_mod... variables).
> 
> > 
> 
> > I also attached video that shows how vim compiled with this patch 
> > (vim.fast) faster than original vim (vim.slow) (there are two sessions on 
> > the video: the first is slow, the second is fast(er)).
> 
> > 
> 
> > Cheers, Alexey.

-- 
-- 
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

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff -r 54d96e3b2eec src/window.c
--- a/src/window.c	Thu May 22 21:22:19 2014 +0200
+++ b/src/window.c	Wed May 28 11:09:54 2014 +0400
@@ -6720,6 +6720,66 @@
 
 #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
 /*
+ * Dirty hack for matchparen and :3match.
+ * Try to detect whether match_add() or match_delete() was called from
+ * matchparen and return best redraw type VALID with set
+ * wp->w_buffer->b_mod_set and values of wp->w_buffer->b_mod_top and 
+ * wp->w_buffer->b_mod_bot calculated from 'pat'.
+ */
+    static int
+optimize_redraw_type(wp, pat, id, def)
+    win_T	*wp;
+    char_u	*pat;
+    int		id;
+    int		def;
+{
+    static regprog_T *regprog = NULL;
+
+    if (id != 3)
+	return def;
+
+    if (regprog == NULL)
+	regprog = vim_regcomp(
+	    "^\\\\(\\\\%\\(\\d\\+\\)l\\\\%\\%(\\d\\+\\)c\\\\)\\\\|"
+	    "\\\\(\\\\%\\(\\d\\+\\)l\\\\%\\%(\\d\\+\\)c\\\\)$", RE_MAGIC);
+
+    if (regprog != NULL)
+    {
+	regmatch_T regmatch;
+
+	regmatch.regprog = regprog;
+	if (vim_regexec(&regmatch, pat, (colnr_T)0))
+	{
+	    linenr_T mod_top = atol(regmatch.startp[1]);
+	    linenr_T mod_bot = atol(regmatch.startp[2]);
+
+	    if (mod_top > mod_bot)
+	    {
+		linenr_T tmp = mod_top;
+
+		mod_top = mod_bot;
+		mod_bot = tmp;
+	    }
+	    if (wp->w_buffer->b_mod_set)
+	    {
+		if (wp->w_buffer->b_mod_top > mod_top)
+		    wp->w_buffer->b_mod_top = mod_top;
+		if (wp->w_buffer->b_mod_bot < mod_bot)
+		    wp->w_buffer->b_mod_bot = mod_bot;
+	    }
+	    else
+	    {
+		wp->w_buffer->b_mod_top = mod_top;
+		wp->w_buffer->b_mod_bot = mod_bot;
+	    }
+	    wp->w_buffer->b_mod_set = TRUE;
+	    return VALID;
+	}
+    }
+    return def;
+}
+
+/*
  * Add match to the match list of window 'wp'.  The pattern 'pat' will be
  * highlighted with the group 'grp' with priority 'prio'.
  * Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
@@ -6739,6 +6799,7 @@
     matchitem_T *m;
     int		hlg_id;
     regprog_T	*regprog;
+    int		redraw_type = SOME_VALID;
 
     if (*grp == NUL || *pat == NUL)
 	return -1;
@@ -6807,7 +6868,9 @@
 	prev->next = m;
     m->next = cur;
 
-    redraw_later(SOME_VALID);
+    redraw_type = optimize_redraw_type(wp, pat, id, redraw_type);
+
+    redraw_later(redraw_type);
     return id;
 }
 
@@ -6823,6 +6886,7 @@
 {
     matchitem_T *cur = wp->w_match_head;
     matchitem_T *prev = cur;
+    int		redraw_type = SOME_VALID;
 
     if (id < 1)
     {
@@ -6846,10 +6910,13 @@
 	wp->w_match_head = cur->next;
     else
 	prev->next = cur->next;
+
+    redraw_type = optimize_redraw_type(wp, cur->pattern, id, redraw_type);
+
     vim_regfree(cur->match.regprog);
     vim_free(cur->pattern);
     vim_free(cur);
-    redraw_later(SOME_VALID);
+    redraw_later(redraw_type);
     return 0;
 }
 

Raspunde prin e-mail lui