Greetings vim-dev,
I have a patch I would like to submit to fix a bug in vim.
Description of the problem and the patch:
===========================
In the code below, place the cursor over the brace { on the end of the
first line.
Press % to jump the cursor to the matching brace.
The cursor jumps to the first brace inside the comment.
This patch modifies that behavior so that the cursor jumps to the
matching brace on the final line.
for( $x = 0; $x < 10; $x++ ) { // Place the cursor on this brace.
if( $x == 4 ) {
echo "x is equal to 4!\n";
}
// } else { echo "x is not equal to 4... =(\n"; }
} // It should jump to this brace, but it does not. This patch
corrects this behavior.
===========================
The patch:
===========================
--- a/src/search.c Sun Dec 16
+++ b/src/search.c Wed Jan 02
@@ -20,6 +20,7 @@
static int check_prevcol __ARGS((char_u *linep, int col, int ch, int
*prevcol));
static int inmacro __ARGS((char_u *, char_u *));
static int check_linecomment __ARGS((char_u *line));
+static int check_hashcomment __ARGS((char_u *line));
static int cls __ARGS((void));
static int skip_chars __ARGS((int, int));
#ifdef FEAT_TEXTOBJ
@@ -1751,6 +1752,8 @@
int match_escaped = 0; /* search for escaped match */
int dir; /* Direction to search */
int comment_col = MAXCOL; /* start of / / comment */
+ int hashcomment_col = MAXCOL; /* start of # comment */
+ int start_in_comment; /* start position is in a comment */
#ifdef FEAT_LISP
int lispcomm = FALSE; /* inside of Lisp-style comment
*/
int lisp = curbuf->b_p_lisp; /* engage Lisp-specific hacks
;) */
@@ -2018,6 +2021,12 @@
do_quotes = -1;
start_in_quotes = MAYBE;
+ // If we start in a line comment or hash comment, then we know
for a fact that we are in comments.
+ // Otherwise we don't know - we may or may not be in a block comment.
+ if( check_linecomment( linep ) < pos.col || check_hashcomment(
linep ) < pos.col )
+ start_in_comment = TRUE;
+ else
+ start_in_comment = MAYBE;
clearpos(&match_pos);
/* backward search: Check if this line contains a single-line comment */
@@ -2249,6 +2258,48 @@
if (start_in_quotes == MAYBE)
start_in_quotes = FALSE;
+ /*
+ * If we find the start of a block comment, set match_pos to
+ * our position. Clear match_pos if we find the end of
+ * the block comment.
+ *
+ * Once we find the start or end of a block comment, we also
+ * know for a fact whether or not we started in a comment.
+ * ( If we were not yet sure... )
+ */
+ if( backwards )
+ {
+ if( linep[pos.col] == '/' && linep[pos.col+1] == '*' )
+ {
+ clearpos(&match_pos);
+ if( start_in_comment == MAYBE )
+ start_in_comment = TRUE;
+ }
+ else if( linep[pos.col] == '*' && linep[pos.col+1] == '/' )
+ {
+ match_pos.lnum = pos.lnum;
+ match_pos.col = pos.col;
+ if( start_in_comment == MAYBE )
+ start_in_comment = FALSE;
+ }
+ }
+ else
+ {
+ if( linep[pos.col] == '/' && linep[pos.col+1] == '*' )
+ {
+ match_pos.lnum = pos.lnum;
+ match_pos.col = pos.col;
+ if( start_in_comment == MAYBE )
+ start_in_comment = FALSE;
+ }
+ else if( linep[pos.col] == '*' && linep[pos.col+1] == '/' )
+ {
+ clearpos(&match_pos);
+ if( start_in_comment == MAYBE )
+ start_in_comment = TRUE;
+ }
+ }
+
/*
* If 'smartmatch' is set:
* Things inside quotes are ignored by setting 'inquote'. If we
@@ -2260,6 +2311,8 @@
* inquote if the number of quotes in a line is even, unless this
* line or the previous one ends in a '\'. Complicated, isn't it?
*/
+ comment_col = check_linecomment( linep );
+ hashcomment_col = check_hashcomment( linep );
switch (c = linep[pos.col])
{
case NUL:
@@ -2363,14 +2416,17 @@
* is what we expect. */
if (cpo_bsl || (bslcnt & 1) == match_escaped)
{
- if (c == initc)
- count++;
- else
- {
- if (count == 0)
- return &pos;
- count--;
- }
+ if( ( pos.col < comment_col && pos.col < hashcomment_col
&& match_pos.lnum == 0 && match_pos.col == 0 && start_in_comment !=
TRUE ) || ( start_in_comment == TRUE ) )
+ {
+ if (c == initc)
+ count++;
+ else
+ {
+ if (count == 0)
+ return &pos;
+ count--;
+ }
+ }
}
}
}
@@ -2445,6 +2501,28 @@
}
/*
+ * Check if line[] contains a hash comment (a comment starting with #).
+ * Example:
+ * # This is a comment.
+ * Return MAXCOL if not, otherwise return the column.
+ * TODO: skip strings.
+ */
+ static int
+check_hashcomment(line)
+ char_u *line;
+{
+ char_u *p;
+
+ p = line;
+
+ p = vim_strchr( p, '#' );
+
+ if( p == NULL )
+ return MAXCOL;
+ return (int)(p - line);
+}
+
+/*
* Move cursor briefly to character matching the one under the cursor.
* Used for Insert mode and "r" command.
* Show the match only if it is visible on the screen.
===========================
Comments and questions welcome, and thanks for taking the time to
consider the patch.
Archer
--
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