Friday, April 19, 2013

Re: Consider lines containing a tab a paragraph boundary

diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -5199,10 +5199,22 @@

*'paragraphs'* *'para'*
'paragraphs' 'para' string (default "IPLPPPQPP TPHPLIPpLpItpplpipbp")
- global
+ global or local to buffer |global-local|
Specifies the nroff macros that separate paragraphs. These are pairs
of two letters (see |object-motions|).

+ If it starts with a slash, the rest of the option is taken as regular
+ expression to test against. If several consecutive lines match the
+ pattern and the cursor is on the first line of it, it will move after
+ all of them. Example, consider this file: >
+
+ foo
+ foo
+ foo
+
+< If the cursor is on the first foo and the 'para' option is set to /foo
+ pressing } will move after the whole block of "foo".
+
*'paste'* *'nopaste'*
'paste' boolean (default off)
global
@@ -5821,11 +5833,16 @@

*'sections'* *'sect'*
'sections' 'sect' string (default "SHNHH HUnhsh")
- global
+ global or local to buffer |global-local|
Specifies the nroff macros that separate sections. These are pairs of
two letters (See |object-motions|). The default makes a section start
at the nroff macros ".SH", ".NH", ".H", ".HU", ".nh" and ".sh".

+ If it starts with a slash, the rest of the option is taken as regular
+ expression to test against. If several consecutive lines match the
+ pattern and the cursor is on the first line of it, it will move after
+ all of them.
+
*'secure'* *'nosecure'* *E523*
'secure' boolean (default off)
global
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -240,8 +240,10 @@
call append("$", "\tcharacter of a line")
call <SID>BinOptionG("sol", &sol)
call append("$", "paragraphs\tnroff macro names that separate paragraphs")
+call append("$", "\t(global or local to buffer)")
call <SID>OptionG("para", &para)
call append("$", "sections\tnroff macro names that separate sections")
+call append("$", "\t(global or local to buffer)")
call <SID>OptionG("sect", &sect)
call append("$", "path\tlist of directory names used for file searching")
call append("$", "\t(global or local to buffer)")
diff --git a/src/option.c b/src/option.c
--- a/src/option.c
+++ b/src/option.c
@@ -144,11 +144,14 @@
# define PV_OFU OPT_BUF(BV_OFU)
#endif
#define PV_PATH OPT_BOTH(OPT_BUF(BV_PATH))
+#define PV_PARA OPT_BOTH(OPT_BUF(BV_PARA))
+#define PV_SECTIONS OPT_BOTH(OPT_BUF(BV_SECTIONS))
#define PV_PI OPT_BUF(BV_PI)
#ifdef FEAT_TEXTOBJ
# define PV_QE OPT_BUF(BV_QE)
#endif
#define PV_RO OPT_BUF(BV_RO)
+#define PV_SECTION OPT_BOTH(OPT_BUF(BV_SECTIONS))
#ifdef FEAT_SMARTINDENT
# define PV_SI OPT_BUF(BV_SI)
#endif
@@ -1916,7 +1919,7 @@
(char_u *)NULL, PV_NONE,
{(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
{"paragraphs", "para", P_STRING|P_VI_DEF,
- (char_u *)&p_para, PV_NONE,
+ (char_u *)&p_para, PV_PARA,
{(char_u *)"IPLPPPQPP TPHPLIPpLpItpplpipbp",
(char_u *)0L} SCRIPTID_INIT},
{"paste", NULL, P_BOOL|P_VI_DEF|P_PRI_MKRC,
@@ -2160,7 +2163,7 @@
#endif
SCRIPTID_INIT},
{"sections", "sect", P_STRING|P_VI_DEF,
- (char_u *)&p_sections, PV_NONE,
+ (char_u *)&p_sections, PV_SECTIONS,
{(char_u *)"SHNHH HUnhsh", (char_u *)0L}
SCRIPTID_INIT},
{"secure", NULL, P_BOOL|P_VI_DEF|P_SECURE,
@@ -5295,6 +5298,8 @@
check_string_option(&buf->b_p_bh);
check_string_option(&buf->b_p_bt);
#endif
+ check_string_option(&buf->b_p_para);
+ check_string_option(&buf->b_p_sections);
#ifdef FEAT_MBYTE
check_string_option(&buf->b_p_fenc);
#endif
@@ -9601,6 +9606,8 @@
#ifdef FEAT_STL_OPT
case PV_STL: return (char_u *)&(curwin->w_p_stl);
#endif
+ case PV_PARA: return (char_u *)&(curbuf->b_p_para);
+ case PV_SECTIONS: return (char_u *)&(curbuf->b_p_sections);
}
return NULL; /* "cannot happen" */
}
@@ -9633,6 +9640,10 @@
? (char_u *)&(curbuf->b_p_ar) : p->var;
case PV_TAGS: return *curbuf->b_p_tags != NUL
? (char_u *)&(curbuf->b_p_tags) : p->var;
+ case PV_PARA: return *curbuf->b_p_para != NUL
+ ? (char_u *)&(curbuf->b_p_para) : p->var;
+ case PV_SECTIONS: return *curbuf->b_p_sections != NUL
+ ? (char_u *)&(curbuf->b_p_sections) : p->var;
#ifdef FEAT_FIND_ID
case PV_DEF: return *curbuf->b_p_def != NUL
? (char_u *)&(curbuf->b_p_def) : p->var;
@@ -10192,6 +10203,8 @@
/* options that are normally global but also have a local value
* are not copied, start using the global value */
buf->b_p_ar = -1;
+ buf->b_p_para = empty_option;
+ buf->b_p_sections = empty_option;
#ifdef FEAT_QUICKFIX
buf->b_p_gp = empty_option;
buf->b_p_mp = empty_option;
diff --git a/src/option.h b/src/option.h
--- a/src/option.h
+++ b/src/option.h
@@ -1029,6 +1029,8 @@
, BV_TX
, BV_UDF
, BV_WM
+ , BV_PARA
+ , BV_SECTIONS
, BV_COUNT /* must be the last one */
};

diff --git a/src/search.c b/src/search.c
--- a/src/search.c
+++ b/src/search.c
@@ -2663,12 +2663,72 @@
#ifdef FEAT_FOLDING
linenr_T fold_first; /* first line of a closed fold */
linenr_T fold_last; /* last line of a closed fold */
- int fold_skipped; /* TRUE if a closed fold was skipped this
- iteration */
+ int fold_skipped; /* TRUE if a closed fold was skipped this iteration */
#endif
+ char_u *section;
+ char_u *par;
+
+ section = (*curbuf->b_p_sections == NUL ? p_sections : curbuf->b_p_sections);
+ par = (*curbuf->b_p_para == NUL ? p_para : curbuf->b_p_para);

curr = curwin->w_cursor.lnum;

+ if ((what == NUL && *par == '/') ||
+ ((what == '{' || what == '}') && *section == '/'))
+ {
+ char_u *pat = NULL;
+ int r = FALSE; /* return value */
+
+ if (what == NUL && *par == '/')
+ pat = (par + 1);
+ else if (*section == '/')
+ pat = (section + 1);
+
+ if (pat != NULL)
+ {
+ int old_wrapscan = p_ws;
+ pos_T cur = curwin->w_cursor;
+ p_ws = FALSE; /* don't wrap around the end of the file */
+ int fwd = (dir == FORWARD);
+
+ do {
+ r = searchit(curwin, curbuf, &curwin->w_cursor, dir, pat,
+ 1L, SEARCH_KEEP | SEARCH_START, RE_SEARCH, 0, NULL);
+
+ /* skip consecutive lines, matching the pattern */
+ while(equalpos(cur, curwin->w_cursor))
+ {
+ if (!searchit(curwin, curbuf, &curwin->w_cursor, dir, pat, 1L,
+ SEARCH_KEEP | (fwd ? SEARCH_END : SEARCH_START ),
+ RE_SEARCH, 0, NULL))
+ break;
+
+ if (dir == FORWARD)
+ incl(&curwin->w_cursor);
+ else
+ decl(&curwin->w_cursor);
+ cur = curwin->w_cursor;
+ searchit(curwin, curbuf, &curwin->w_cursor, dir, pat, 1L,
+ SEARCH_KEEP | SEARCH_START | (fwd ? 0 : SEARCH_END),
+ RE_SEARCH, 0, NULL);
+ }
+
+ } while (r && count-- > 0);
+ p_ws = old_wrapscan;
+ if (!r)
+ {
+ if (dir == FORWARD)
+ curwin->w_cursor.lnum = curwin->w_buffer->b_ml.ml_line_count;
+ else
+ curwin->w_cursor.lnum = 1L;
+ }
+ setpcmark();
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
while (count--)
{
did_skip = FALSE;
@@ -2765,13 +2825,20 @@
int both;
{
char_u *s;
+ char_u *section;
+ char_u *par;
+
+ section = (*curbuf->b_p_sections == NUL ? p_sections : curbuf->b_p_sections);
+ par = (*curbuf->b_p_para == NUL ? p_para : curbuf->b_p_para);

s = ml_get(lnum);
if (*s == para || *s == '\f' || (both && *s == '}'))
return TRUE;
- if (*s == '.' && (inmacro(p_sections, s + 1) ||
- (!para && inmacro(p_para, s + 1))))
+ if (*s == '.' && (inmacro(section, s + 1) ||
+ (!para && inmacro(par, s + 1))))
return TRUE;
+ if (*section == '/' || *par == '/')
+ return inmacro(section, s) || (!para && inmacro(par, s));
return FALSE;
}

diff --git a/src/structs.h b/src/structs.h
--- a/src/structs.h
+++ b/src/structs.h
@@ -1595,6 +1595,8 @@
#ifdef FEAT_PERSISTENT_UNDO
int b_p_udf; /* 'undofile' */
#endif
+ char_u *b_p_para; /* 'paragraph' local value */
+ char_u *b_p_sections; /* 'sections' local value */

/* end of buffer options */

On Fr, 12 Apr 2013, zappathustra@free.Fr wrote:

> Indeed. Actually, the bar should be preceded by three backslashes, if
> I'm not mistaken (two denote a single one, and the last escapes the
> bar).
>
> In the meanwhile I've found that if you're on a paragraph line, you
> can't jump to paragraph lines just below if you're one the first
> character. E.g.:
>
> set paragraphs=foo
>
> with file:
>
> foo
> foo
>
> foo
>
> If you're on the first "f", you'll jump to the last line; if you're on
> the first "o", you'll jump to the second line... With file:
>
> foo
> foo
> foo
>
> you won't jump anywhere from the first "f". Normally, "}" with the
> usual 'paragraphs':
>
> - jumps to the next blank line when on a non-blank line;
> - jumps to the next blank line following a non-blank line when on a
> blank line;
> - jumps to the end of the file if there is no blank line below the
> current one.
>
> (``Blank line'' here of course means a real blank lines or the nroff
> macros.)
>
> With Christian's patch, I think that behavior should be mimicked by
> simply replacing ``(non-)blank line'' with ``line (not) matching the
> option''.

Here is an updated toy patch. I also made the 'section' and 'para'
settings global-local.

Note, there is one problem and I don't know how to approach it.

Consider this file
,----
|
| foo
| foo
| foo
|
`----

If the cursor is on the first foo and you have set para=/foo pressing }
will jump after the whole 'foo' block. If the cursor is on the first o
and you press '}' it will first move to the second 'foo' line and on
next press of '}' it will move over the whole block.

I have no clue, how to detect, whether the cursor is on a block of
consecutive lines matching the 'para' or 'section' pattern and in that
case jump over the complete block. Perhaps, when using a regular
expression for 'para' and 'sections', we shouldn't jump over consecutive
matching lines at all?

Apart from that inconsistency, the patch seems to work for me.

regards,
Christian

--
--
You received this message from the "vim_use" 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_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

No comments:

Post a Comment