I want to write macro for substitution with confirmation, something like :%s/old/new/gc, where old and new are constantly changing (they are dynamically constructed by the same macro). but i cant stop recording the macro while typing colon command, and after entering that command, i have confirmation prompt replace with new (y/n/a/q/l/^E/^Y)? As you see, typing q now will quit the substitute command, and not stop the macro.
So, what i want:
i want macro, which will execute :%s/old/new/gc as i need to confirm each substitution.
Or some other automated solution for that problem. Maybe there is a way to stop recording macro while entering a colon command?
You could try regular expressions for the search replace. The following should do what's described above.
%s/a:\(\w\{-}-\{-}fact\)/a:sld-\1/gc
See:
http://vimregex.com/
http://regexone.com/
Related
In my normal workflow in Vim, I sometimes realize after the fact that I could have recorded a macro after making a bunch of edits to a line. I then record the macro and type out the actions again for another line, before using the macro.
I would like to record all of the actions run on a single line to a macro, after the fact. Is this possible?
I have not tried anything yet, because I do not know if this command exists.
No, you can't record something after it happened.
I have the following problem
This is text:
printf("sysname %s",ut.sysname);
I want to use vim to replace sysname line by line. I type the command in my gvim:
:s/sysname/version
I want to get the output like this:
printf("version %s",ut.version);
But I get the output like this:
printf("version %s",ut.sysname);
What am I doing wrong?
you're missing the g command that applies to all matches on current line, instead of only the first one:
:s/sysname/version/g
as a bonus:
:%s/sysname/version/g
will replace all occurences in current file, not only on the current line.
To do it on one line
:s/sysname/version/g
You can also use the qq macro recorder before typing that in, and press q after, and then use #q to replay that on any other lines you want to replace that on. Or press : up to select old commands.
Or to do it on every single line:
:%s/sysname/version/g
However with replacing every line you should be careful. If there is a lot of text try making your replacements more specific.
I would do
:%s/\(printf("\)sysname\(.*\)sysname/\1version\2version
My problem is when I create a vim macro, I used some search and replace in the search and replace history. So I use the arrow key to go up in the history to find it. But the trouble is the macro only record my arrow key activity not the command I find. So when I execute the macro again, the search history is changed and the result are messed up. Is there any way to solve this?
Yes, you can solve this problem by understanding that macros record keystrokes, not the result of commands, and act accordingly.
For example, when you use the previous search with <C-r>/ or //, the actual content of the last search register is not recorded. The next time you play that macro, the last search pattern will probably be different and your whole macro will be busted if you expect otherwise. You must actually type the search pattern or perform the search as part of the recording if you want your macro to be reliable.
To get a better grasp of how recording works in Vim, you can paste the macro you just recorded (macros are saved in registers, just like the stuff you yank) and study what's there.
qq
(do stuff)
q
"qp
Remember this fact and don't use such history recall commands when you record a macro. It may be not as convenient, but you'll probably amortize the effort over the repeated macro applications, anyway.
Actually, the shrewd practitioner can use this behavior of macros as a feature. By e.g. referring to the last search pattern (e.g. :s//...) or recalling a partial command (e.g. :w foo<Up>), one can record macros that are applicable to a wide variety of situations.
Finally, you can "salvage" a macro after you realize it's broken; as its contents are stored in a register, you can just re-edit, e.g. via:
:let #a = <C-r><C-r>=string(#a)<CR>
I've to replace all occurrences of a specific macro inside some(only some amongst dozens) C functions. Since the file is thousands of lines long, with several instances of the macro in all the functions, I'd like to replace all occurrences within the particular function the cursor is currently placed.
I know VIM provides navigation commands (like [[ to go to the beginning of the current function, and then % to find its matching closing brace) , but I can't figure out how to use them to come up with the required search-replace command.
Can anyone help ?
Place your cursor on the first opening brace. Then type v% and you will see the function body get highlighted. Then type the replacement command :s/find/replace/g and hit enter. This will replace within the selected function.
Note: You will see you command prompt change to: :'<,'>:s/find/replace/g.
Although I would also recommend dogbane's solution, I thought I'd also mention the NrrwRgn plug-in. It's quite useful for working on a continuous subset of a buffer.
Say I have the following style of lines in a text file:
"12" "34" "some text "
"56" "78" "some more text"
.
.
.
etc.
I want to be able to remove the quotes surrounding the first two columns. What is the best way to do this with Vim (I'm currently using gVim)?
I figured out how to at least delete the beginning quote of each line by using visual mode and then enter the command '<,'>s!^"!!
I'm wondering if there is a way to select an entire column of text (one character going straight down the file... or more than 1, but in this case I would only want one). If it is possible, then would you be able to apply the x command (delete the character) to the entire column.
There could be better ways to do it. I'm looking for any suggestions.
Update
Just and FYI, I combined a couple of the suggestions. My _vimrc file now has the following line in it:
let #q=':%s/"\([0-9]*\)"/\1/g^M'
(Note: THE ^M is CTRLQ + Enter to emulate pressing the Enter key after running the command)
Now I can use a macro via #q to remove all of the quotes from both number columns in the file.
use visual block commands:
start mode with Ctrl-v
specify a motion, e.g. G (to the end of the file),
or use up / down keys
for the selected block specify an action, e.g. 'd' for delete
For more see
:h visual-mode
Control-V is used for block select. That would let you select things in the same character column.
It seems like you want to remove the quotes around the numbers. For that use,
:%s/"\([0-9]*\)"/\1/g
Here is a list of what patterns you can do with vim.
There is one more (sort of ugly) form that will restrict to 4 replacements per line.
:%s/^\( *\)"\([ 0-9]*\)"\([ 0-9]*\)"\([ 0-9]*\)"/\1\2\3\4/g
And, if you have sed handy, you can try these from the shell too.
head -4 filename.txt | sed 's/pattern/replacement/g'
that will try your command on the first 4 lines of the file.
Say if you want to delete all columns but the first one, the simple and easy way is to input this in Vim:
:%!awk '{print $1}'
Or you want all columns but the first one, you can also do this:
:%!awk '{$1="";$0=$0;$1=$1;print}'
Indeed it requires external tool to accomplish the quest, but awk is installed in Linux and Mac by default, and I think folks with no UNIX-like system experience rarely use Vim in Windows, otherwise you probably known how to get a Windows version of awk.
Although this case was pretty simple to fix with a regex, if you want to do something even a bit more advanced I also recommend recording a macro like Bryan Ward. Also macros come easier to me than remembering which characters need to be escaped in vim's regexes. And macros are nice because you can see your changes take place immediately and work on your line transformation in smaller bits at a time.
So in your case you would have pressed qw to start recording a macro in register w (you can of course use any letter you want). I usually start my macros with a ^ to move to the start of the line so the macro doesn't rely on the location of the cursor. Then you could do a f" to jump to the first ", x to delete it, f" to jump to the next " and x to delete that too. Then q to finish recording.
Instead of making your macro end on the next line I actually as late as today figured out you can just V (visually line select) all lines you want to apply your macro to and execute :normal #w which applies your macro in register w to each visually selected line.
See column editing in vim. It describes column insert, but basically it should work in the same way for removing.
You could also create a macro (q) that deletes the quotes and then drops down to the next line. Then you can run it a bunch of times by telling vi how many times to execute it. So if you store the macro to say the letter m, then you can run 100#m and it will delete the quotes for 100 lines. For some more information on macros:
http://vim.wikia.com/wiki/Macros
The other solutions are good. You can also try...
:1,$s/^"\(\w\+\)"/\1/gc
For more Vim regex help also see http://vim.wikia.com/wiki/Search_patterns.
Start visual-block by Ctrl+v.
Jump at the end and select first two columns by pressing: G, EE.
Type: :s/\%V"//g which would result in the following command:
:'<,'>s/\%V"//g
Press Enter and this will remove all " occurrences in the selected block.
See: Applying substitutes to a visual block at Vim Wikia