4

i wanted to search and replace, implement after the thread here, unfortunately it does not work. gVim find/replace with counter

Can anyone help me?

Working

:let n=[0] | %s/|-\n|/\=map(n,'v:val+1')/g

Not working

:let n=[0] | %s/|-\n|/BLABLA\=map(n,'v:val+1')/g

Why? how do I mask the functionon?

Example

{| class="wikitable"
! Number
! Name
! Type
! Default Value
! Duration
! Activation
! Status
! EDIT
|-
| 
| Adobe-Dummy-Cart-Total
| Custom Script
| 
| Pageview
| Active
| Approved
| Edit
|-
| 
| basePrice

I wana replace

|-
|

with

|-
| 1

|-
| 2
Hendrik
  • 65
  • 3

3 Answers3

2

:help sub-replace-expression (emphasis mine)

When the substitute string starts with "\=" the remainder is interpreted as an expression.

You cannot do what you want; the replacement string is either a subexpression (when it starts with \=), or a literal (when it does not).

Instead, you need to rewrite the subexpression to concatenate the string programmatically (:help expr-.):

:let n=[0] | %s/|-\n|/\="BLABLA".map(n,'v:val+1')[0]/g

[0] to take the content of the array produced by map is necessary for two reasons: replacing with an array will introduce an unwanted newline, and make concatenation with a string impossible.

For your example though, it may not necessary, if you are not introducing any string besides the number - i.e. if you don't need that space (:help /\zs):

:let n=[0] | %s/|-\n|\zs/\=map(n,'v:val+1')[0]/g

Of course, you can combine the two, for a perfect demoisturised solution to your specific situation:

:let n=[0] | %s/|-\n|\zs/\=" ".map(n,'v:val+1')[0]/g
Amadan
  • 191,408
  • 23
  • 240
  • 301
  • +1, great answer! Thanks! a very good explanation. That helped me a lot. Thank you. I did some research after that and came across the explanation here. https://jeffkreeftmeijer.com/vim-reformat-dates/ – Hendrik Jan 28 '19 at 10:19
  • You've come to the right conclusions, but the mentioning of the `/\=` regexp multi at the beginning is just confusing and wrong, as this is in the _replacement_ part, not in the _pattern_ part. – Ingo Karkat Jan 28 '19 at 11:17
  • @IngoKarkat Oh gods you're right... I must be overworked to confuse those two lol... Thanks for the heads up – Amadan Jan 28 '19 at 11:28
  • Overworked on a Monday morning... oh that's bad! Better take the whole week off ;-) – Ingo Karkat Jan 28 '19 at 11:42
2

When you use :help sub-replace-expression, the entire replacement must be a Vimscript expression (that starts with \=). You cannot just prepend replacement text (as in BLABLA\=map(n,'v:val+1'). Use string concatentation instead. A complication with your map approach is that this returns a List, not a String, so we need to select the only (counter) element of the List. To refer to the existing matched text, use submatch(0) instead of \0 or & (or avoid the need for a reference by using \zs at the end of the pattern instead).

:let n=[0] | %s/|-\n|/\=submatch(0) . " " . map(n,'v:val+1')[0]/g
Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • +1 für genaue Erklärung! Hallo Ingo, danke für die gute Antwort und eine genaue Erklärung. Jetzt verstehe ich was damit gemeint ist. Werde auf jeden Fall mich mit den Thema mehr befassen. – Hendrik Jan 28 '19 at 14:12
  • Ah, glad I could help! Please accept one answer (the one that you prefer) by clicking on the outlined checkmark. This way, the question is marked as closed, and you increase your chances of getting answers to future questions, as this shows that you care about the answers. – Ingo Karkat Jan 28 '19 at 14:26
0

Using \zs we can make the solution easier

:let c=1 | g/^|-\n|\zs/ s//\=' '.c/g | let c+=1

^ ............ start of line
\n ........... line break
|  ........... vertical bar

We are concatenating a space \=' ' with the counter c

SergioAraujo
  • 11,069
  • 3
  • 50
  • 40