sed と vi の :s の違いハック
s/hoge/meso/3
としたとき、sed は行内で3番目の hoge を置換するが、vi はカレント行から3行以内の hoge を置換する。
sed 流の方がうれしいので vim もそうなるようにハックにチャレンジしてみた。
複数行にわたる検索パターンが指定されたときは考えないことに。
--- ../src.orig/ex_cmds.c Sun Apr 23 03:56:56 2006 +++ ex_cmds.c Thu Dec 7 23:38:08 2006 @@ -4142,6 +4144,8 @@ linenr_T old_line_count = curbuf->b_ml.ml_line_count; linenr_T line2; long nmatch; /* number of lines in match */ + int matchcount; + int nth = 0; linenr_T sub_firstlnum; /* nr of first sub line */ char_u *sub_firstline; /* allocated copy of first sub line */ int endcolumn = FALSE; /* cursor in last column when done */ @@ -4326,10 +4331,13 @@ EMSG(_(e_zerocount)); return; } + /* eap->line1 = eap->line2; eap->line2 += i - 1; if (eap->line2 > curbuf->b_ml.ml_line_count) eap->line2 = curbuf->b_ml.ml_line_count; + */ + nth = i; } /* @@ -4389,6 +4397,8 @@ #endif ); ++lnum) { + matchcount = 0; + sub_firstlnum = lnum; nmatch = vim_regexec_multi(®match, curwin, curbuf, lnum, (colnr_T)0); if (nmatch) @@ -4475,6 +4485,8 @@ */ for (;;) { + matchcount += 1; + /* Save the line number of the last change for the final * cursor position (just like Vi). */ curwin->w_cursor.lnum = lnum; @@ -4523,6 +4535,11 @@ goto skip; } + if (nth && matchcount < nth) { + do_again = TRUE; + goto skip; + } + if (do_ask) { /* change State to CONFIRM, so that the mouse works
[追記:2007-01-13]
ed は sed と同じ挙動になる。
vi になって改悪されたわけだ。
ex-050325 のソースを見ると
ex_re.c
445 setcount(); 446 newline();
としているのでバグではないようだが…