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