15

Normally, a substitute with the c option gives me two options: (y)es or (n)o. Is it possible to have several numbered yes options to choose from?

Example

File

person: Alice
dog: Tobby
person: Bob

Pattern 1 :%s/person:/woman:/c

Pattern 2 :%s/person:/man:/c

Pattern 1 and 2 have the same search pattern but different replacement patterns. I want to unify them into one pattern with the option of pressing (1) for replacement 1, (2) for replacement 2 or (n) for no replacement.

19

The implementation of :s//c is fixed; what you're looking for is replacement with a Vimscript expression (:help sub-replace-expr). You can query a single-digit via getchar(), or prompt for longer numbers via input():

:%s/person:/\=get(['woman', 'man'], getchar() - char2nr(1), submatch(0)) . ':'/
:%s/person:/\=get(['woman', 'man'], input('Your choice: ') - 1, submatch(0)) . ':'/

You can enter a higher number (3 in your example) to perform no replacement.


If you need this often, it would make sense to define a custom Query() function for that. In there, you could also add a :redraw, so that you see the replacements that have already happened.

  • The command seems problematic. Only after I add the check command it works: :%s/person:/\=get(['woman', 'man'], input('Your choice: ') - 1, submatch(0)) . ':'/c – Lerner Zhang Mar 19 '17 at 3:15
  • But add the c command will result in I need two steps to replace a string, which I think is needless. – Lerner Zhang Mar 19 '17 at 3:17
1

Thanks for all the upvotes to my original question! I've now incorporated a :SubstituteChoices command into my PatternsOnText plugin, which provides a robust implementation. The example in the question would be solved via:

:%SubstituteChoices/person:/woman:/man:/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.