Case preserving substitute in Vim
Nobody in this thread understands vim. They think vim is about fancy things like submatch, and plugins. To solve a simple problem, they write terrible code which is only usable in vim. Can’t even re-use it in a script.
vim, like unix, is not about fancy and complicated commands
vim is fundamentally a text editor within the unix operating system. Like other unix programs, its main value is playing really nicely with other programs.
In particular, you can pipe lines to any unix executable and write the result back into vim. An executable written in any language. Not stupid vim (only) script or emacs (only) lisp. But a language you already know. To write a generally reusable executable.
So, with this in mind, here’s a simple solution to the problem of a special find and replace.
I’ll punt the general case presented in stack overflow because I only care about something that does both:
foo → bar
Foo → Bar
for arbitrary foo and bar.
It takes 17 lines of clean python, and 1 line of clean vim.
Here’s the python:
#!/usr/bin/env python3 import sys find = sys.argv replace = sys.argv lines = sys.stdin.readlines() for i in range(len(lines)): Find = find.upper() + find[1:] Replace = replace.upper() + replace[1:] lines[i] = lines[i].replace(find, replace) lines[i] = lines[i].replace(Find, Replace) for l in lines: print(l, end='')
This python is saved as an executable “csfar” in my PATH.
To use it in vim, I select my range (say, with v), and type 1 line of vim:
!csfar foo bar
And it Just Works. Here’s a video: https://www.loom.com/share/6f62cf25b738468888243d6761f76c33
This is the power of vim. Flawless integration with an arbitrary executable.
Not some stupid submatching function nobody knows.