Hi Bram,

this patch fixes this issue from the todo list:


,----
| 8   Add a command to jump to the next character highlighted with 
| "Error".
`----

It implements the [e and ]e movement commands, which move to the 
previous or next error. And while I was at it, I also made [t ]t move to 
the previous/next item that is highlighted with TODO highlighting.

regards,
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
diff --git a/runtime/doc/motion.txt b/runtime/doc/motion.txt
--- a/runtime/doc/motion.txt
+++ b/runtime/doc/motion.txt
@@ -1289,6 +1289,25 @@
 ]*  or  ]/		go to [count] next end of a C comment "*/".
 			|exclusive| motion. {not in Vi}
 
+						        *]e*
+]e			go to [count] next item that is highlighted as an
+			error. Needs |:syntax-on| |exclusive| motion.
+			{not in Vi}
+
+						        *[e*
+[e			go to [count] previous item that is highlighted as an
+			error. Needs |:syntax-on| |exclusive| motion.
+			{not in Vi}
+
+						        *]t*
+]t			go to [count] next item that is highlighted as TODO
+			item. Needs |:syntax-on| |exclusive| motion.
+			{not in Vi}
+
+						        *[t*
+[t			go to [count] previous item that is highlighted as
+			TODO item. Needs |:syntax-on| |exclusive| motion.
+			{not in Vi}
 
 						*H*
 H			To line [count] from top (Home) of window (default:
diff --git a/src/normal.c b/src/normal.c
--- a/src/normal.c
+++ b/src/normal.c
@@ -185,6 +185,7 @@
 #ifdef FEAT_AUTOCMD
 static void	nv_cursorhold __ARGS((cmdarg_T *cap));
 #endif
+int  syn_move_to __ARGS((int, int, int));
 
 static char *e_noident = N_("E349: No identifier under cursor");
 
@@ -6329,7 +6330,7 @@
     curwin->w_set_curswant = TRUE;
 
     i = do_search(cap->oap, dir, pat, cap->count1,
-			   opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, NULL);
+			   opt | SEARCH_OPT | SEARCH_ECHO,  NULL);
     if (i == 0)
 	clearop(cap->oap);
     else
@@ -6684,6 +6685,25 @@
 	    clearopbeep(cap->oap);
     }
 #endif
+    /*
+     * "[e" and "]e": move to previous or next error highlight
+     * "[t" and "]t": move to previous or next TODO highlight
+     */
+    else if (cap->nchar == 'e' || cap->nchar == 't')
+    {
+	if (syn_move_to(cap->cmdchar == ']' ? FORWARD : BACKWARD,
+			cap->count1, cap->nchar == 'e' ?
+			syn_name2id((char_u *) "Error") :
+			syn_name2id((char_u *)"todo")) == FAIL)
+	    clearopbeep(cap->oap);
+	else
+#ifdef FEAT_FOLDING
+	{
+	    if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP)
+		foldOpenCursor();
+	}
+#endif
+    }
 
 #ifdef FEAT_DIFF
     /*
@@ -9457,3 +9477,68 @@
     cap->retval |= CA_COMMAND_BUSY;	/* don't call edit() now */
 }
 #endif
+
+/*
+ * Move to next syntax error.
+ * dir is forward or backward, attr is Highligh group to look for
+ */
+    int
+syn_move_to(dir, count, attr)
+    int		dir;		/* FORWARD or BACKWARD */
+    int		count;
+    int	        attr;
+{
+    pos_T	pos;
+#ifdef FEAT_SYN_HL
+    int		has_syntax = syntax_present(curwin);
+#endif
+    int         (*func) __ARGS((pos_T *));
+    int         found = FALSE;
+
+#ifdef FEAT_SYN_HL
+    if (has_syntax)
+    {
+	pos = curwin->w_cursor;
+
+	if (dir == FORWARD)
+	  func = inc;
+	else
+	  func = dec;
+
+	while (count--)
+	{
+	    while (check_syn_id((pos_T *) &pos, attr))
+	    {
+	        /* if the cursor is already at an error,
+		 * move over it first
+		 */
+		if ((*func)(&pos) == -1)
+		  return FAIL;
+	    }
+	    for (;;)
+	    {
+	        found  = check_syn_id((pos_T *) &pos, attr);
+		if (!found)
+		{
+		    if ((*func)(&pos) == -1)
+		    /* Stop at end of file or start of file*/
+			return FAIL;
+		}
+		else
+		  break;
+	    }
+	}
+	if (found)
+	{
+	    setpcmark();
+	    curwin->w_cursor = pos;
+	    adjust_cursor_col();
+	    return found;
+	}
+	else
+	    return FAIL;
+    }
+#endif
+    else
+        return FAIL;
+}
diff --git a/src/proto/syntax.pro b/src/proto/syntax.pro
--- a/src/proto/syntax.pro
+++ b/src/proto/syntax.pro
@@ -19,6 +19,7 @@
 int syn_get_sub_char __ARGS((void));
 int syn_get_stack_item __ARGS((int i));
 int syn_get_foldlevel __ARGS((win_T *wp, long lnum));
+int check_syn_id __ARGS((pos_T *found_pos, int synid));
 void init_highlight __ARGS((int both, int reset));
 int load_colors __ARGS((char_u *name));
 void do_highlight __ARGS((char_u *line, int forceit, int init));
diff --git a/src/syntax.c b/src/syntax.c
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -6471,6 +6471,45 @@
 }
 #endif
 
+/* 
+ * Check whether the given syntax id matches
+ * at the specified position (follows links)
+ */
+
+    int
+check_syn_id(found_pos, synid)
+    pos_T       *found_pos;
+    int         synid;
+{
+    int         t_attr;
+    struct hl_group *c_attr;
+    int         found = FALSE;
+
+    t_attr = syn_get_id(curwin, found_pos->lnum, found_pos->col,
+	    TRUE, NULL, FALSE);
+    c_attr = &HL_TABLE()[t_attr - 1];
+    /* Don't know, why a syntax attribute can't have a
+    * name, but a link, but check here anyways to avoid a crash
+    * */
+    while (c_attr->sg_name != NUL && c_attr->sg_link != NUL)
+    {
+	if (t_attr == synid)
+	{
+	    found = TRUE;
+	    break;
+	}
+	else
+	{
+	    t_attr = c_attr->sg_link;
+	    c_attr = &HL_TABLE()[t_attr-1];
+	}
+    }
+    if (t_attr == synid)
+	found = TRUE;
+
+    return found;
+}
+
 #endif /* FEAT_SYN_HL */
 
 /**************************************

Raspunde prin e-mail lui