I have some text like this:
foo<space><space><space>'bar'
When I do da' inside 'bar', the whitespace is removed:
foo
How can I do da' without removing whitespace, so I get this as the result?
foo<space><space><space>
I found this in vim's help topic on text-objects:
i" *v_iquote* *iquote*
i' *v_i'* *i'*
i` *v_i`* *i`*
Like a", a' and a`, but exclude the quotes and
repeating won't extend the Visual selection.
Special case: With a count of 2 the quotes are
included, but no extra white space as with a"/a'/a`.
Thus, doing the below would not delete the whitespace.
d2i'
For more help on text objects, do :help text-objects
This is covered in :help v_i':
For the "a" commands: The operator applies to the object and the white
space after the object. If there is no white space after the object
or when the cursor was in the white space before the object, the white
space before the object is included.
So, the problem is that you're at the end of the line. To change the behavior, you can add a whitespace, go back, and then issue the command: A<Space><Esc>hda'.
Alternatively, use the inner object, and remove the two quotes afterwards, as in di'hxx.
For the quote text objects, there's even a handy special case, so d2i' looks like the winner here:
Special case: With a count of 2 the quotes are
included, but no extra white space as with a"/a'/a`.
Related
This question already has answers here:
In Vim, how can I delete everything between quotes including the quotes?
(3 answers)
Closed 2 years ago.
if I have the following text:
['abc']
and the cursor on the first quote.
dw gives me [abc']
d2w gives me [']
d3w gives me [
so, how can I delete 'abc' and keep []
d i [
To delete everything inside square brackets
Use da'.
The a' text object selects the text under the cursor surrounded by single quotes, including the quotes themselves.
See :help a':
"a quoted string". Selects the text from the previous quote until the next quote.
This text object is quite smart, if there are multiple quoted strings in a line, Vim will figure out which pairs make out strings. Vim can also recognize escaped quotes inside a string (the default escape character is \, but even that you can configure through the 'quoteescape' option.)
There are a few options for single lines:
"Cut til" with ct] or "delete til" with dt]. More info is available here (you can delete backwards, yank til, etc).
"Delete find" (delete through target): df'
Visual line/find: Ctrl+vf'x. Verbose but gives some agency to adjust as needed.
In a comment you mention you have a multi-element list and want to remove an item. The contents of the element matter; I usually proceed in an ad-hoc manner, using combinations of dw and x or the visual line/find with w or small adjustments near the target to clip out the element in addition to techniques above.
For example, if your list is ['one', 'two', 'three'] and your cursor is over the first ', you can use dfspacebar or x2dw to produce ['two', 'three'].
Other useful threads:
Delete everything between two brackets in Vim, including newlines
Vim - delete until (inclusive) character in multiple lines
In Vim, how can I delete everything between quotes including the quotes?
It may be a bit counterintuitive at the start, but you can use "search&replace" for these type of tasks.
In vim, you are looking for :s Vim WiKi, find the string 'abc' and replace it with empty string.
You should use something like Don mentioned.
While #ggorlen's answer about d f space is great, some people might find it beneficial to use a mapping which works regardless of where the cursor is position on the word, something like:
nnoremap [something] :normal vf,oF'xx<CR>
Will remove the 'one' element in the below example no matter where on the one it is.
['one', 'two', 'three'] => ['two', 'three']
To delete trailing whitespace on a line or across a file I can do:
:[range]s/\s\+$//
However, I was wondering for a single line in normal mode if there's an easier approach, for example if the line is:
Hi, I am a line |
And my cursor is past the e, is there a more generic command than doing dTe in normal mode? The next best I could find was dg_, but that goes one too far. And then, one more option might be gElD.
Generic way without :substitute
Use diw to delete multiple whitespace (including tabs) while the cursor is on one of the whitespaces (like in the example).
This works for any whitespace sequence: trailing, leading, etc.
Use dw to delete from the cursor to the end of the sequence. This is useful when you want to re-indent a line or fix alignment.
As this is independent of the first/last character of the previous/next word this is the most generic way.
Using a mapping with :substitute
Use nmap <leader>tr :%s/\s\+$// to remove all trailing whitespace in the whole buffer by pressing \tr (assuming the original mapleader)1.
Replace tr with what ever suits you best.
Omit the the % in the mapping to make it only work on the current line.
--
As a side note: Use set list listchars=trail:· to show trailing whitespace (replace · with any character you like).
--
1 Removing all whitespace may not be what you want, especially when using a version control system and the file contains whitespace not added by yourself.
I am looking to remove all white space in vim, but keep the default indentation as is. Currently all out files use spaces instead of tabs so:
content
content inside[Sneeky white space of epicness]
content
Should be:
content
content inside
content
Note: [Sneeky white space of epicness] represents a block of white space.
Use substitute
%s/ *$//g
$ means end of line.
* means match zero or more instances of the previous element (as suggested by Jite)
Be aware that you could have tab... To represent any white space, use \s
%s/\s*$//g
EDIT:
As suggested by kojiro you could use + instead of *. With a *, vim does the replace on EVERY line. With a +, the replace is done only where it needs to be done in that case.
+ means match at least one instance of the previous element.
With vim you have to escape the +.
See :help pattern-overview for more details.
My final answer :
%s/\s\+$//g
There are several plugins that can detect and (on demand, or even automatically) delete trailing whitespace. My DeleteTrailingWhitespace plugin is one of them, and handles way more cornercases that the simple :%s command usually given. (The plugin page has links to alternative plugins.)
In Vim, if I have code such as (in Ruby):
anArray << [anElement]
and my cursor is on the first [, I can hop to ] with the % key, and I can delete all the content between the [] pair with d%, but what if I just want to delete the [ and ] leaving all the remaining content between the two. In other words, what's the quickest way to get to:
anArray << anElement
One can take advantage of the text objects that are built in into Vim
(see :help text-objects). The desired edit can be stated as a
sequence of the following three actions.
Cut the text inside the square brackets:
di[
Select the (empty) square brackets:
va[
Alternatively, you can just select the character under the
cursor and the one to the left of it, because the command
from step 1 always puts the cursor on the closing bracket:
vh
Paste the cut text over the selected brackets:
p
Altogether, it gives us the following sequence of Normal-mode commands:
di[va[p
or, when the alternative form of step 2 is used:
di[vhp
ma%x`ax (mark position in register a, go to matching paren, delete char, go to mark a, delete char).
EDIT:
%x``x does the same thing (thanks to #Alok for the tip).
Using the Surround plugin for Vim, you can eliminate surrounding delimiters with ds<delimeter>.
To install it via Vundle plugin, add
Plugin 'tpope/vim-surround'
to your .vimrc file and run :PluginInstall.
If you have issues with the marks pointing to the first char of the line or with using % ...
di[vhp
works as well... It deletes matching [] brackets, when the cursor is anywhere inside. '[' can be replaced by '{' or '(' .
The other answers work fine if you want to delete delimiters one line at a time.
If on the other hand you want to remove a function and it's delimiters from the entire file use:
:%s/function(\(.*\))/\1/g
which replaces function(arguments) with arguments everywhere in the file.
You can use d% while your cursor is on the bracket/parentheses.
Say I have ten lines and I want to prepend text to some word that occurs in those lines? It does not have to be at the beginning of the line.
From:
sdfsd foo sdfsd
sfsd foo fsdf
sdfsdf foo sdfsdf
to:
sdfsd bar(foo sdfsd
sfsd bar(foo fsdf
sdfsdf bar(foo sdfsdf
Is it also possible to not only prepend the bar( but actually surround foo with bar(foo)?
I would also like a quick way to append // comments to multiple lines (C-style comments).
I use Vim/GVim 7.2.
Go to the first foo, press Ctrl-v to enter visual block mode and press down until all the lines with foo are marked. Then press Shift-i to insert at the beginning (of the block). When you are finished and press Esc, the inserted characters will be added to each line at the left of the marked block.
To insert at the end, press again Ctrl-v, move up/down to mark all affected lines and then press End or $ to extend the selection until the end of the lines. Now you can press Shift-a to append at the end of all the lines, just like previously with Shift-i.
The visual selection can also be done with normal movement commands. So to comment a whole block in C you could move to the opening brace and type Ctrl-v % Shift-i // Esc.
To answer your first question, the below
:%s/foo/bar(&)/g
will look for foo, and surround the matched pattern with bar(). The /g will do this multiple times in one line.
Since you're just matching foo, you could do a simple :s/foo/bar(foo)/g. The above will work, however, if you decide to match on a regular expression rather than a simple word (e.g. f[a-z][a-z]). The '&' in the above represents what you've matched.
To prefix a set of lines I use one of two different approaches:
One approach is the block select (mentioned by sth). In general, you can select a rectangular region with ctrl-V followed by cursor-movement. Once you've highlighted a rectangle, pressing shift-I will insert characters on the left side of the rectangle, or shift-A will append them on the right side of the rectangle. So you can use this technique to make a rectangle that includes the left-most column of the lines you want to prefix, hit shift-I, type the prefix, and then hit escape.
The other approach is to use a substitution (as mentioned by Brian Agnew). Brian's substitution will affect the entire file (the % in the command means "all lines"). To affect just a few lines the easiest approach is to hit shift-V (which enables visual-line mode) while on the first/last line, and then move to the last/first line. Then type:
:s/^/YOUR PREFIX/
The ^ is a regex (in this case, the beginning of the line). By typing this in visual line mode you'll see '<,'> inserted before the s automatically. This means the range of the substitution will be the visual selection.
Extra tip: if your prefix contains slashes, you can either escape them with backslash, or you can use a different punctuation character as the separator in the command. For example, to add C++ line comments, I usually write:
:s:^:// :
For adding a suffix the substitution approach is generally easier unless all of your lines are exactly the same length. Just use $ for the pattern instead of ^ and your string will be appended instead of pre-pended.
If you want to add a prefix and a suffix simultaneously, you can do something like this:
:s/.*/PREFIX & SUFFIX/
The .* matches the whole line. The & in the replacement puts the matched text (the whole line) back, but now it'll have your prefix and suffix added.
BTW: when commenting out code you'll probably want to uncomment it later. You can use visual-block (ctrl-V) to select the slashes and then hit d to delete them, or you can use a substitution (probably with a visual line selection, made with shift-V) to remove the leading slashes like this:
:s:// ::
:normal to the rescue!
:%norm Wibar(
:%norm WEa)
:norm(al) replays the commands as if you had typed them:
W - goes to the next word
i - starts insertion mode
bar( - types the sequence 'bar('
Or in one line:
:%norm Wibar(ctrlvESCEa)
If you're running Windows then type ctrlq instead of ctrlv.
Yet another possibility (probably not-so-useful in your test case, but handy in other situations) is to cordon off the area you want to change with marks.
Put the cursor anywhere in the top line and press 'a
Put the cursor anywhere in the last line and press 'b
Issue the command :'a,'b s/foo/bar(&)/
I usually like visual block mode if everything is visible on the screen, and I usually prefer marks if the start and stop are separated by many screens.
Another simple regular expression is:
%s/^/<text you want to prepend>/
For the C-style comments, use the regexp answer by Brian, and match on line ending $, and insert away.