Vim: same change to all line-endings of selected lines? - vim

In https://stackoverflow.com/a/11790464/5354137, there is a very detailed description how to, e.g. perform the same insert to the beginnings of all selected lines by placing the cursor over the first character of the first line, then after <C-v> moving down, then Isomething<Esc><down> inserting something everywhere.
But how does one do the same thing in the case of lines of unequal length, such as:
'Lorem ipsum
'dolor sit amet,
'consectetur adipiscing elit,
'sed do...
to their respective line endings? E.g. if I wanted to insert ', after m, ,, , and ., how would I do that without resorting to :substitute? (Or to a plugin, just using original vim-fu...)

Substitute (original answer)
The easiest way to do it is with the :substitute command. Select the lines in visual mode and then do:
:'<,'>s/$/',/<CR>
The $ stands for the end of the line. Note that vim will already write the :'<,'> part, so you only have to type from there.
Using a macro
With the question having been updated and :substitute off the table, I'd suggest recording a macro. Place the cursor on the line with "Lorm ipsum" and do:
qaA',<Esc>jq
then call the macro three times for the remaining lines. Either by hitting # a lot:
#a####
or with the more elegant
3#a
Using a recursive macro
As commented by #AndR, it's possible to record a macro that calls itself which will run until it reaches the end of the buffer:
qaqqaA',<Esc>j#aq
Note that the macro already calls itself with #a.
Afterwards, call #a and single quotes will be appended to every line until the end of the buffer.
Without visual selection
Both #AndR's answer using :normal and my :substitute answer above rely on a visual selection of the lines to modify. It is possible without that by typing in a range or line numbers. For "Lorem ipsum..." on lines 1 through 4, type either of the two commands:
:1,4s/$/',/
:1,4norm A',
This has the benefit that it works without a visual selection and from anywhere in the buffer.

Based on your reference link and reproduction steps, this is your problem halfway:
But how does one do the same thing in the case of lines of unequal length ...
Follow the link and use the first method Using only visual-block mode, let's start with step 5:
Select any column, hit <C-v> to enter visual-block mode and expand your selection toward the bottom:
'Lo[r]em ipsum
'do[l]or sit amet,
'co[n]sectetur adipiscing elit,
'se[d] do...
Hit $ or <End> (see :help $), will get the selection like this:
'Lo[rem ipsum]
'do[lor sit amet,]
'co[nsectetur adipiscing elit,]
'se[d do...]
Hit A',<Esc> to achieve your goal:
'Lorem ipsum',
'dolor sit amet,',
'consectetur adipiscing elit,',
'sed do...',
Note and supplement:
If you use the latest Vim9 and your virtualedit option contains block, when you hit $ or <End>, you may see this selection (Vim8 won't):
'Lo[rem ipsum ]
'do[lor sit amet, ]
'co[nsectetur adipiscing elit, ]
'se[d do... ]
This could be a issue with the VIM9 or an intentional design? I don't know, but don't care, just press A. You'll see your cursor at the end of the first line, which is fine (| is the cursor position):
'Lorem ipsum|
'dolor sit amet,
'consectetur adipiscing elit,
'sed do...
Then you enter the text you need (e.g. ',) and <Esc> ends editing, it works fine:
'Lorem ipsum',
'dolor sit amet,',
'consectetur adipiscing elit,',
'sed do...',
As a supplement, oppositely, if you want to insert text in the same column where has no text when there are irregular endings : You can add block to your virtualedit option (see :h 'virtualedit'), using other left-right-motions (e.g. l or |) instead of $ to get this selection:
'Lo[rem ipsum ]
'do[lor sit amet, ]
'co[nsectetur adipiscing elit, ]
'se[d do... ]
When you press A, the cursor will be at (| is the cursor position):
'Lorem ipsum |
'dolor sit amet,
'consectetur adipiscing elit,
'sed do...
Then enter the text you want (e.g. ',), hit <Esc> to obtain:
'Lorem ipsum ',
'dolor sit amet, ',
'consectetur adipiscing elit, ',
'sed do... ',

Here the goal can be achieved by appending ' at the end of each line. In one line you'd normally do A'. In order to do this this in each line of the visual selection, run
:<,>norm A'
Assuming that you have selected the needed lines visually (with v or V).
See :h :normal for details.

Related

ST3 - Expand Selection to Word and Quick Find Next - Double Assignment of cmd + d on Mac OS in Sublime Text 3.1.1 (B3176)

Apologies in advance if this is the incorrect forum for this question - I am an absolute beginner when it comes to programming of any sort.
It seems that the Expand Selection to Word (Menu > Selection > Expand Selection to Word) functionality in ST3 has been assigned the same keyboard shortcut as the Quick Add Next (Menu > Find > Quick Add Next).
However, even if one clicks on these options manually (ie without making use of the keyboard shortcuts), the effect is the same: clicking on "Expand Selection to Word" simply finds the next matching strong and adds it to the current selection.
So now I'm wondering if I've just fundamentally misunderstood the intended purpose, even though the language seems unambiguous.
Could someone please confirm these functions should behave differently, and
If so, how can I fix the behaviour so that I can make use of the expand selection to word functionality?
Thank you in advance for you time and help!
The short answer to your question is that indeed both of these items are the same thing, placed in two different places and bound to the same key. The reason for that is that the command does multiple things, depending on the situation that you use it in, which makes it fit into both places.
For what it's worth, the operation of this particular command is commonly a stumbling block for newer users because there's a bit of subtlety to what it does (which is outlined below).
For verification that this is the same command;
Use Preferences > Key Bindings to open the key bindings window; in the left hand pane, search for find_under_expand; you see this particular key binding (on MacOS it uses super instead of ctrl) :
{ "keys": ["ctrl+d"], "command": "find_under_expand" },
Use View Package File from the Command Palette, then open Default/Main.sublime-menu and perform the same search; there are multiple hits for the same command in different menu items:
{ "command": "find_under_expand", "caption": "Expand Selection to Word" },
{ "command": "find_under_expand", "caption": "Quick Add Next" },
You can also open the console with View > Show Console, enter sublime.log_commands(True), then trigger the commands and see in the console that the same command is being executed regardless of which of the key bindings or menu commands you use.
Cycling back to the top, the command find_under_expand is often a stumbling block for newer users to Sublime because it does different things depending on the situation. This makes it quite powerful and useful, but can catch you unaware initially.
Specifically, there are a couple of things that the command might do:
If there is at least one caret that has no selection, and all carets with no selection are inside of a word, selection at every "empty" caret is expanded to cover the word under that caret. Thus, this command works as Expand Selection to Word in the menu.
If all carets are not "empty", and all selections contain the same text, the command looks for the next occurrence of the selected text and adds it to the selection by adding a new caret there and selecting it. Thus, this command works as Quick Add Next as well.
For example, here's the content of the standard lorem snippet:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
If you put the caret in the first dolor on line 1 and hit the key, the text dolor will be selected. This is #1 triggering; the caret has no selection and is in a word, so the selection is expanded. Pressing the key a second time, the dolor in line 4 is added to the selection. This is #2 triggering; the next occurrence of the text is found and selected.
Now we can reset things by pressing Escape to go back to a single selection, and moving the cursor so that we're back to a single caret and no selected text.
Now put the caret in dolor and hit the key to select it again, as before. This time, use a Ctrl+Click on the word amet to add a second caret at that location. Now we have two carets, one selecting the text dolor and one inside of amet. If you hit the key now, you get #1 happening; the amet is added to the selection, but no matter how many more times you press it, the dolor on line 4 is not added to the selection. The #2 item above only triggers when all of the selections contain the same text.
Reset again as above, and this time manually select the word dolor on line 1 by using Shift along with your arrow keys. Pressing the key now may give you a bit of a surprise; part of the word dolore on line 2 is selected and added to the selection. Pressing a third time selects the dolor on line 4, and one more press gives you part of dolore on line 5 as well.
So clearly, this command does both things; it will expand the selection at the cursor out to the current word, but it will also try to find other instances of the selected text and add them as well.
The part of this that often messes with people's heads is that last example. As we saw in the first case, when we let Sublime select the word for us with the key press, continued presses ensure that only that exact text is found and added. However if you manually select the text first, the command selects all instances of the text, even if it's not a whole word.
This is incredibly powerful because you can for example easily rename variables by first expanding the selection to the variable name, then by selecting all instances and typing a new name. There's no worry that you might select partial variable names. However if you need to select partial words, that is available to you as well.

Variable-width hanging indents in vim?

This isn't a programming question per se, since I'm aiming to use this for note-taking -- but there just isn't any community more reliable for in-depth vim knowledge than this one.
What I'd like to do is set a hanging indent in vim - you know, the kind that looks like this:
Lorem ipsum dolor sit amet consectetur
adipisicing elit neque amet fuga
dolores voluptatem aspernatur
explicabo quasi. Nostrum...
Except I know you can do this with
set formatoptions+=2
What I'd really like is for vim to automatically set the width of the indent based on the presence of a special character in the first line. For instance, I might want to set this special character to ":" to format my text like so:
Lorem: Ipsum porro dolorem nostrum
incidunt similique a? Eaque
minus aliquid dolorem veritatis
omnis odit.
Quidem: distinctio quibusdam distinctio
accusamus alias magnam.
Voluptatem: dignissimos exercitationem
deleniti aliquam ratione?
Necessitatibus expedita
praesentium.
In my ideal scenario, this would also be compatible with vim's breakindent setting, which visually indents soft-wrapped lines (officially included in vim as of patch 7.4.338).
Does anyone know if this is possible - or even if this functionality can be achieved with a plugin?

How to paste same text in Multiple Position of Multiple Line on Vim

I'm switching my TextEditor from Sublime Text to Vim with iTerm2 recently.
I'm looking for a plugin to paste text in Multiple Position of Multiple Line on Vim.
(Similar to the multicursor on Sublime Text which I can select cursor and use CMD+Click to select in other position then paste.)
I've seen vim-multiple-cursors plugin but it will only allow me to select the same word of next occurrence.
e.g - to place cursor at different location on different line as below.,
Line 1: Lorem ipsum dolor sit amet, [CURSOR HERE] consectetuer adipiscing elit. Aenean
Line 2: commodo ligula [CURSOR HERE] eget dolor. Aenean massa. Cum sociis natoque
Line 3: penatibus et magnis dis parturient montes,[CURSOR HERE] nascetur ridiculus mus.
Line 4: Donec [CURSOR HERE] quam felis, ultricies nec, pellentesque eu,pretium quis, sem.
Your help would be greatly appreciated and Many Thanks in advance.
VIM Version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Apr 21 2014 14:54:22)
MacOS X (unix) version
Warning
I recommend against trying to port your previous editing habits unchanged to Vim; after all, Vim's mode-based editing and command-based syntax are its distingishing features and make editing highly efficient.
Vim way
The "Vim way" would be more like using a regular expression to specify the places, moving to the first match, pasting, and then repeating with n and .
Emulation
You can sort-of emulate your intended workflow by manually inserting a marker char (e.g. §) at each location, and then replacing it via:
:%s/§/\=##/g
This uses :help sub-replace-expr to replace with the default register's contents.
Vim has a different buffer that stores what you have copied. To paste you just have to use "P" and the content is pasted.
Or I would recommend you to use "." [dot] - in Vim it is used for last action. So, once you have written/copied and pasted it in one line, you can just use the "dot" everywhere you want the same text to be pasted (i.e. last action to be taken).
The canonical Vim way to do that, the "dot formula" as coined by Drew Neil, is the reverse of the Sublime Text way.
In Sublime, you mark each match of a pattern, before doing the change :
mark Cmd+D
mark Cmd+D
mark Cmd+D
mark Cmd+D
change foo
In Vim, you "mark" a pattern, do the change once and repeat it on further instances of that pattern:
mark *N
change ciwfoo<Esc>
repeat n.
repeat n.
repeat n.
But, since you have 7.4, you can use the "new" gn normal mode command/motion:
nnoremap <key> *``cgn
and shorten the process above to:
change <key>foo<Esc>
repeat .
repeat .
repeat .
repeat .
Which is not that bad, I think.

Swap all occurrences of two strings [duplicate]

This question already has answers here:
What is the easiest way to swap occurrences of two strings in Vim?
(5 answers)
Closed 8 years ago.
Say, for example, I have a document with all pairs of parenthesis flipped:
Lorem )ipsum( dolor )sit( amet
And I want to correct it to be:
Lorem (ipsum) dolor (sit) amet
Of course I can't make the swap with two replacements; first replace all ( with ) and then all ) with (, because then I will end up with:
Lorem (ipsum( dolor (sit( amet
Please provide a way to do it in vim for any pair of strings.
Update:
Thanks ernix for a good answer. For those wondering what the tr function does:
http://vimdoc.sourceforge.net/htmldoc/eval.html#tr()
using vimscript:
:%call setline(".", tr(getline("."), "()", ")("))
or simply call tr:
:%!tr ')(' '()'
update
If you consider about white spaces, then Kent's answer is the best :)
%s/\(\s*\((\|)\)\s*\)/\=substitute(submatch(0),submatch(0),submatch(2)=='('?') ':' (', 'g')/g
this line will do it:
:s/[()]/\=substitute(submatch(0),submatch(0),submatch(0)==')'?'(':')','g')/g
it looks lengthy because the function name submatch(, you can write a little function or assign the match part to a var.
with nice idea from ernix:
s/[()]/\=tr(submatch(0),')(','()')/g
One trivial method:
%s/(/1UnIqUe1/g
%s/)/(/g
%s/1UnIqUe1/)/g

vim copy and replace text

Lets say that i have this text:
$test = 'lorem';
$test2= 'ipsum';
and I want to copy lorem and paste into ipsum.
I tried to do yi' on lorem and then went on ipsum and did ci' but that replaced my pastebin with ipsum. and my previous copy was lost.
yi' on lorem, move to i of ipsum, vep?
Easy:
"kyi' on lorem, move to i of ipsum, ve"kp
This yanks lorem into register k, pastes it over ipsum from register k, and keeps it in register k ready to paste again anywhere else you might want to put it. ipsum still ends up in the default register, but that's no longer a problem and could be useful too.
If you've already got something in register k, you can use a different register instead (just use a different key).
I usually go to the sed command.
:%s/ipsum/lorem/g
% means do this for every line
s means sed, or search and replace
g at the end means replace every ipsum with lorem; if you omit this, it only replaces the first.
Go to the l of lorem, ye (yank to end of word).
Go to the i of ipsum, "_de (delete to end of word, putting the deleted text in the black hole register.
P (paste register before cursor).
Altogether: yej"_deP
Why don't you yank into a named buffer, using "ayi', then delete and paste with d'i"aP?
I'm not sure what do you want exactly.
You have this on two lines:
$test = 'lorem';
$test2= 'ipsum';
If you go to l and yw, it yanks lorem,
then go to i of ipsum, and cw, and p and it will replace ipsum with lorem.
You will still have both lorem and ipsum in the registers.
You can get the contents of those registers with :reg
If you want to paste something from them then "*p, or ":p, or "0p (you'll see it when you type :reg)
vi'y on lorem
vi'p on ipsum
gvy to copy back lorem to register for possible macro with vi'p
(qa - gvy - j - vi'p - q - #a - ## - ## ...)
Words here to stop Markdown treating the code that follows as plain text.
/lorem
"adw
/ipsum
"aP"bdw
``
"bp
The first text searches for 'lorem'; the next deletes the word into the buffer named 'a', leaving a pair of empty quotes behind in the text. The next search finds 'ipsum'; the "aP pulls the buffer named 'a' in before the word ipsum; the "bdw deletes the word into the buffer named 'b', leaving 'lorem' behind. The double back-tick goes back to the place the last search came from - the empty quotes; and "bp pulls the named buffer after the first quote.
You can also omit the "a and "b, but this way, the values are in the named buffers "a and "b and can be copied again, and again, and again until you don't need the values any more.
After you do ci' on impsum your lorem is in register "0. So, you can do ci'^R0 (^R means Ctrl+r) and paste your lorem in place of ipsum.
See :help quote_number for more info on numbered registers.
You want to use y to copy a selection and p to paste.
Here is a good list to keep handy.

Resources