Skip to main content
added 141 characters in body
Source Link
Mass
  • 14.4k
  • 1
  • 23
  • 48

You cannot use \= in the "search" portion of a :substitute command to introduce an expression. Actually, \= does have meaning in this context but it "matches 0 or 1 of the preceding atom, as many as possible," which is not what you want.

Instead, you should use <c-r>=b:commentChar<cr>. This means literal CTRL-R= to introduce an expression and then <cr> to end the expression (copy and pasting this won't work). Your substitute also uses () which means literal parentheses, not a group. Here is a working command:

:s/\v(^\s*)\V<c-r>=escape(b:commentChar, '\/')<cr>\v\s*/\1/

This command:

  • uses \v to make parentheses act as a group- not strictly necessary but it prevents the user's magic setting from interfering.
  • \V before the enterexpression to allow literal text and \v afterwards.
  • escape() so we don't have to worry about any slashes in the expression so we can safely use s//. Using s@@ works too, but there is the (maybe remote) possibility that b:commendCharcommentChar contains @. escape handles all cases.

Again <c-r> and <cr> are literal characters you must type. This is handled transparently in mappings, e.g., copy and pasting the following would work

nnoremap <leader>c :s/\v(^\s*)\V<c-r>=escape(b:commentChar, '\/')<cr>\v\s*/\1/<cr>

Alternatively, you could use execute:

execute 's/\v(^\s*)\V'.escape(b:commentChar, '\/').'\v\s*/\1/'

You cannot use \= in the "search" portion of a :substitute command to introduce an expression. Actually, \= does have meaning in this context but it "matches 0 or 1 of the preceding atom, as many as possible," which is not what you want.

Instead, you should use <c-r>=b:commentChar<cr>. This means literal CTRL-R= to introduce an expression and then <cr> to end the expression (copy and pasting this won't work). Your substitute also uses () which means literal parentheses, not a group. Here is a working command:

:s/\v(^\s*)\V<c-r>=escape(b:commentChar, '\/')<cr>\v\s*/\1/

This command:

  • uses \v to make parentheses act as a group- not strictly necessary but it prevents the user's magic setting from interfering.
  • \V before the enter literal text.
  • escape() so we don't have to worry about any slashes in the expression so we can safely use s//. Using s@@ works too, but there is the (maybe remote) possibility that b:commendChar contains @. escape handles all cases.

Again <c-r> and <cr> are literal characters you must type. This is handled transparently in mappings, e.g., copy and pasting the following would work

nnoremap <leader>c :s/\v(^\s*)\V<c-r>=escape(b:commentChar, '\/')<cr>\v\s*/\1/<cr>

You cannot use \= in the "search" portion of a :substitute command to introduce an expression. Actually, \= does have meaning in this context but it "matches 0 or 1 of the preceding atom, as many as possible," which is not what you want.

Instead, you should use <c-r>=b:commentChar<cr>. This means literal CTRL-R= to introduce an expression and then <cr> to end the expression (copy and pasting this won't work). Your substitute also uses () which means literal parentheses, not a group. Here is a working command:

:s/\v(^\s*)\V<c-r>=escape(b:commentChar, '\/')<cr>\v\s*/\1/

This command:

  • uses \v to make parentheses act as a group- not strictly necessary but it prevents the user's magic setting from interfering.
  • \V before the expression to allow literal text and \v afterwards.
  • escape() so we don't have to worry about any slashes in the expression so we can safely use s//. Using s@@ works too, but there is the (maybe remote) possibility that b:commentChar contains @. escape handles all cases.

Again <c-r> and <cr> are literal characters you must type. This is handled transparently in mappings, e.g., copy and pasting the following would work

nnoremap <leader>c :s/\v(^\s*)\V<c-r>=escape(b:commentChar, '\/')<cr>\v\s*/\1/<cr>

Alternatively, you could use execute:

execute 's/\v(^\s*)\V'.escape(b:commentChar, '\/').'\v\s*/\1/'
Source Link
Mass
  • 14.4k
  • 1
  • 23
  • 48

You cannot use \= in the "search" portion of a :substitute command to introduce an expression. Actually, \= does have meaning in this context but it "matches 0 or 1 of the preceding atom, as many as possible," which is not what you want.

Instead, you should use <c-r>=b:commentChar<cr>. This means literal CTRL-R= to introduce an expression and then <cr> to end the expression (copy and pasting this won't work). Your substitute also uses () which means literal parentheses, not a group. Here is a working command:

:s/\v(^\s*)\V<c-r>=escape(b:commentChar, '\/')<cr>\v\s*/\1/

This command:

  • uses \v to make parentheses act as a group- not strictly necessary but it prevents the user's magic setting from interfering.
  • \V before the enter literal text.
  • escape() so we don't have to worry about any slashes in the expression so we can safely use s//. Using s@@ works too, but there is the (maybe remote) possibility that b:commendChar contains @. escape handles all cases.

Again <c-r> and <cr> are literal characters you must type. This is handled transparently in mappings, e.g., copy and pasting the following would work

nnoremap <leader>c :s/\v(^\s*)\V<c-r>=escape(b:commentChar, '\/')<cr>\v\s*/\1/<cr>