Vi/vim copy text from block that passes a symbol - vim

Assuming that I have a block of text like the picture attached, is there a vim command that would enable me to copy all the text from each line that goes to the left or to the right of the "=" sign for example? The use here is to not spend time having to manually rewrite all of them or copy the block of text then trim away the text unnecessary, but instead copy what is directly wanted.

I would simply…
yank the whole block to a named register:
"ayip
put it somewhere:
"ap
remove the right side of each assignment:
:'[,']normal! ^ElD
put another copy of the initial block somewhere else:
"ap
remove the left side of each assignment:
:'[,']normal! $Bhd0
but there are so many ways to approach that problem, even without knowing how you want to use each side of the assignments…

Related

What is the VIM way to copy a list of variables (a list of words vertically aligned with different widths)?

let(:aaaaa) { 123 }
let(:bb) { true }
let(:ccc_ccc) { "foo bar" }
I want to copy all variable names (:aaaaa, :bb, :ccc_ccc).
In VsCode, for example, I would use a multi-line selection.
How can I do it in VIM?
Block selection didn't work, once the variable names have a different length.
You could use the command :%norm f:"Qyt) to make your 'q register' contain the
following:
:aaaaa:bb:ccc_ccc
The way it works is as follows:
:%norm means 'to all lines, apply the following normal commands'
f: moves the cursor to the first colon on the line
"Qy appends yanked text to the 'q' register
t) is a motion 'till the next closing parenthesis
This assumes that the 'q' register is already empty (you can use qqq to clear
it). If you only want to do this for a subset of lines, you'd replace the %
with a range (or visual selection).
What you do with the register's contents after that is up to you.
"qp will put them into the buffer, and maybe you'd then do :s/:/\r:/g to
split the lines at the colons like this:
:aaaaa
:bb
:ccc_ccc
If your immediate goal is to have something like this in the default register:
:aaaaa
:bb
:ccc_ccc
then it won't be easy to achieve without the ability to visually select multiple non-contiguous pieces of text of arbitrary length, which Vim doesn't have out of the box.
This means that, if we don't want to use a multiple cursors plugin, we are left with more pedestrian ways involving substitutions, macros, etc.
Assuming the cursor is on the first line, you could do something like:
:,+2t+2 " copy the block below itself
:'[,s/.*(\(.*\)).*/\1 " remove everything you don't need
:'[,d " cut the three lines to the unnamed register
But Vim works best when it is used with intent. "Copy this" is rarely a goal in and of itself: it generally is one of the several low-level steps necessary to complete a higher-level task (which itself might be one of the steps of another even higher-level task). What one intends to do with the copied text often plays an important role in choosing the best strategy. Here, your actual goal may have been to get the three variable names on three lines right below their definition, something that actually doesn't imply copying them, so the two first steps would have been enough.

Vim command to paste over highlighted word

I've only recently learned about use v command to mark a section I want to copy or cut. This is great!
But I'd like to use the v command to make the section I want to replace.
For example:
$another_obj->method_in_obj
$self->method_actually_in_obj
I want to mark "another_obj" and overwrite "self" with "another_obj". Basically I want to tell vim that, I want to take these 4 characters (self) and turn them into these 11 characters (another_obj) and have vim adjust my line accordingly.
So the final should be:
$another_obj->method_in_obj
$another_obj->method_actually_in_obj
Thanks!
#Kent has outlined the basic approach: You yank the source word, then paste over the selected replacement. The downside is that you can do that only once, because that action overrides the original yanked text! To avoid that, you need to specify the black-hole register.
I do this so often, I wrote a plugin to simplify and allow maximum speed: ReplaceWithRegister.
This plugin offers a two-in-one gr command that replaces text covered by a {motion} / text object, entire line(s) or the current selection with the contents of a register; the old text is deleted into the black-hole register, i.e. it's gone. It transparently handles many corner cases and allows for a quick repeat via the standard . command. Should you not like it, its page has links to alternatives.
cursor on [a]nother, pressing yw
then j cursor is on [s]elf, press:vawp

Can I move to end of text inside tag with one move?

Let's say I have some HTML:
<tag>Here is a bunch of text which is pretty long.</tag>
My cursor is on H.
I want to add some more text after the period. That is, I want to append text inside of the tag.
Right now, I'd probably $ to the end of the line and then b until I get to the .
The end of the text inside the tag is not predictable, so I can't use f..
What's the fastest way to get to the end of the text inside a tag?
This might not be the best way but one way to do this is to use vit to visually select the inner tag block. And then type A to append to the visually selected region.
So the command is
vitA
And if you just want your cursor at the end of the tag just use
vit<esc>
I would do t<a instinctively.
But I like FDinoff's method better.
It's not one move but this gets the work done.
Assuming that you are in normal mode. Enter the following commands
vatA
What this does is, it visually selects the block including the tag and appends at the end of the line.

How to visually select lines based on a search pattern in vim?

I've got some method calls all over the place in a large file, I'd like to match these lines, select and then yank them as one so I can put them all in a single place.
I can find all the lines I want with :g/>set but how do I visually select each line?
You can't have multiple visual selections in Vim.
But you can clear a register and append all the matching lines to it:
:let #a = ''
:g/>set/y A
then create an empty buffer (or navigate to an existing one):
:vnew
and paste from register a:
"ap
But you probably want something like TagList or TagBar.
edit
:[something]y a
means "yank into register a".
:[something]y A
means "append to register a".
What I usually do is :
Remove all the lines without the pattern :v/pattern/d
Select the whole new file with ggyG
Paste somewhere the result with p
Use undo a few times with u to get the file back to its initial state
This is a bit cumbersome, I would welcome a simpler solution.

Append general buffer to the end of every line in VI

I'm trying to add the contents of the general buffer to the end of every line. I'm sure this is fairly simple, however, an hour of google searches have lead me nowhere.
This is what my file looks like
::Things to bring camping
--matches
--tent
--sleeping bags
--inflatable bed
--firewood
--camping stove
--skillet
I want to add "::Things to bring camping" to the end of every line.
This is i have figured out so far.
/:: -> brings me to the line in question
Y -> yanks the entire line to the general buffer
I tried :%s/$/\p -> this added a "p" to the end of every line.
My problem is with step 3. How do I tell the "search and replace command" to used the "p" (the contents of the general buffer) instead of the "p" the character
Thank you so much for your help.
Just a suggestion: If you try doing it with a macro, you will be able to use 'p' to add the contents of the general buffer.
Sorry, I had to go into vim and find out.
The way to copy your entire line while in command mode, is:
^r "
(that's CTRL and r, then " )
That should paste the entire line you yanked into your search and replace command
For step three, instead of \p, you should use ctrl-R-a. Hold down the control key and type an uppercase "R", continue holding control, and type a lowercase "a".
For a line with multiple words, use ctrl-R-" instead.
I agree with using a macro - they're very powerful.
In this case I took your list example and positioned it at the first colon.
I used y$ to grab the remainder of the line in the buffer.
Then I recorded the macro - I chose 1.
q1
j$pq
Then you can call it for any number of rows in your list. E.g. 10#1
Learned something figuring this one out ...
:%s/$/\=getreg()/
The \= says that what follows is an expression to be evaluated, and the getreg() call gets the contents of the register, by default the "general buffer" as it used to be called by vi.

Resources