Hi,

I would like to propose a patch which suppresses the conversion of
<NL> to <CR> when evaluaation ('\=') is used inside substitute()
function.
Simply this patch is what makes x == y true in the following code.

 let x = substitute('a', '.', "\n", "")
 let y = substitute('a', '.', '\="\n"', "")

The current implementation forces the conversion without regard to the
kind of target, buffer or string. Actually we don't have any way to
replace something with the string containing "\n" with use of
evaluation
('\=') used inside substitute() function.

By this patch, for example, the following code works as we expect.

 let s:table = {'\\':'\', '\r':"\r", '\n':"\n" }
 let s:str = '\\\r\n'
 let s:rep = substitute(s:str, '\\\\\|\\r\|\\n',
'\=s:table[submatch(0)]', 'g')

And this patch does not affect to the result of :substitute
command. Simply, the conversion of <NL> to <CR> is done as it has
been.

In addition, this patch copes with the recursive call of substitute.
Any
combination of :substitute command and substitute() function works.
However
the use of evaluation ('\=') should be limited once as it has been.

The key is the use of the static variable reg_line_lbr in regexp.c.
This variable is true if "\n" in string is line break according to the
comment it regexp.c. Actually, the current implementation set true if
the target is buffer, vice versa if the target is string.
Just to make sure, refer to the use of vim_regexec_multi() in do_sub()
and the use of vim_regsub() in do_string_sub().

This issue has been discussed on the thread of vim_use group;

http://groups.google.com/group/vim_use/browse_thread/thread/5b94dab308193660

Please refer to it, either if you have not.

Regards,

Motoya Kurotsu

======================= attachment ==========================

--- vim73/src/regexp.c  2011-03-06 16:45:15.000000000 +0900
+++ vim73.1/src/regexp.c        2011-03-09 10:36:09.000000000 +0900
@@ -6872,6 +6872,7 @@
 static regmmatch_T     *submatch_mmatch;
 static linenr_T                submatch_firstlnum;
 static linenr_T                submatch_maxline;
+static int             submatch_line_lbr;
 #endif

 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) ||
defined(PROTO)
@@ -6998,6 +6999,7 @@
            submatch_mmatch = reg_mmatch;
            submatch_firstlnum = reg_firstlnum;
            submatch_maxline = reg_maxline;
+           submatch_line_lbr = reg_line_lbr;
            save_reg_win = reg_win;
            save_ireg_ic = ireg_ic;
            can_f_submatch = TRUE;
@@ -7009,9 +7011,10 @@

                for (s = eval_result; *s != NUL; mb_ptr_adv(s))
                {
-                   /* Change NL to CR, so that it becomes a line
break.
+                   /* When NL means a line break, change NL to CR,
+                    * so that it becomes a line break.
                     * Skip over a backslashed character. */
-                   if (*s == NL)
+                   if (*s == NL && !submatch_line_lbr)
                        *s = CAR;
                    else if (*s == '\\' && s[1] != NUL)
                    {
@@ -7021,7 +7024,7 @@
                         *   abc\
                         *   def
                         */
-                       if (*s == NL)
+                       if (*s == NL && !submatch_line_lbr)
                            *s = CAR;
                        had_backslash = TRUE;
                    }
@@ -7044,6 +7047,7 @@
            reg_mmatch = submatch_mmatch;
            reg_firstlnum = submatch_firstlnum;
            reg_maxline = submatch_maxline;
+           reg_line_lbr = submatch_line_lbr;
            reg_win = save_reg_win;
            ireg_ic = save_ireg_ic;
            can_f_submatch = FALSE;

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

Raspunde prin e-mail lui