Delete lines with highlighted text / delete highlighted text - vim

Does anyone know how to delete:
lines with highlighted text
all highlighted text self
(highlighted text (p.e. after a search) not selected text)
Is there a command which search all highlighted text and delete the line?
(independent which search command or function I used to highlight text)
the g/pattern/d command does not always delete the highlighted text
p.e. /^\(.*\)\(\n\1\)\+$ --> highlight all double lines
but g/^\(.*\)\(\n\1\)\+$/d --> does NOT delete all double lines

Well, you can delete the searched pattern this way:
:%s/<pattern>//gc
And you can delete the whole line with the searched pattern this way:
:g/<pattern>/d

In addition to sixfeetsix' answer:
to delete all lines NOT containing <pattern>, type :g!/<pattern>/d or :v/<pattern>/g
to avoid having to type <pattern> after :g/, type :g/CTRL-r//d which inserts the content of the search register (CTRL-r/ means register /) into your command being typed.

how to delete: 2) all highlighted text self
You could use search-and-replace (substitute) to do this.
It is generally used like this:
:%s/your_search_here/your_replacement_here/gc
More specifically, replace your search results with nothing (to remove them):
:%s/your_search_here//gc
Omit the c at the end to replace all without confirmation.
Type :help :s for more info.
how to delete: 1) lines with highlighted text
To delete whole lines, you could either do a substitute, and just match the whole line with a regular expression (%s/^.*your_search_here.*\n//g), or you could use the multiple repeats (multi-repeat) feature.
It is generally used like this:
:g/your_search_here/[cmd]
More specifically, combine it with the normal command you use to delete a line (d):
:g/your_search_here/d
Type :help :g for more info.
Tips:
An easy way to get your query right before doing your substitute is to do your search in command mode rather than the default mode.
Instead of:
/your_search_here
Type:
:/your_search_here
Then you can go to command mode (:), hit the up key to bring up your last search, and edit the line to convert it to a substitute.

From this SuperUser answer:
You can use gn in version 7.4 onwards (and gN to go backwards). It replaces the v//e trick.
Search forward for the last used search pattern, like with `n`, and start Visual mode to select the match.
See :help gn or this Vimcast for more information.

I guess it's the essentially the same question as this:
Vim: when matching string across multiple lines using \_. in regex, yank command only works for the first line
It looks like a bug in Vim.

Related

Vim advanced multiline edits

I'm trying to getting into using more advanced vim features.
How would people go about for the following edit?
from this:
ssn=token_payload.fnr,
fname=token_payload.displayName,
email=token_payload.email,
login=token_payload.username,
to this:
ssn=token_payload['fnr'],
fname=token_payload['displayName'],
email=token_payload['email'],
login=token_payload['username'],
Command line :norm command
I would apply the following normal commands to all lines in the file:
" note that in the real command, <Esc> would be a literal
" press of the escape key (see explanation below)
:%norm f.s['<Esc>f,i']
apply to the whole file: %
the following normal mode commands:norm
move to the period: f.
substitute with opening square bracket and quote: s['
escape insert mode (press ctrl+v to enter a literal character, then escape -
you'll see a gray symbol appear): ^[
move to the comma: f,
insert the quote and closing square bracket: i']
I started using the command line way instead of macros recently since I find
that you can think it over more easily (particularly if you compose the command
in the command buffer with q: - see :help command-buffer).
Use a macro
Another way is to record a macro:
qa0f.s['<Esc>f,i']<Esc>jq
Which you can then deploy on the current line with #a and repeat with ##.
Or use :%norm #a to run the macro on each line.
It's basically the same as above, but instead of :%norm you use qa to
record into the a register (you can use any letter). Then perform the edit. I
added a drop down one line with j before stopping the recording with q.
You can edit the macro after recording it by pasting the contents of the
register ("ap), edit them, and yank them back ("ay$) before replaying it.
Using an external tool
If I wanted to perform multiple substitutions with a single command, I would
filter the text through an external program like sed:
:%!sed "s/\./['/; s/,$/'],/"
One more g[ood] thing
An extremely powerful tool is the :g[lobal] command! (see :help :g) I've
been using it a lot in combination with the norm command. For example, if I
wanted to get all the paragraphs in a document formatted nicely, but not affect
indented text (which could be code blocks, or tables etc.) I would do:
:%g/^\w/norm gqap
This means, for any line with a letter at the very start of the line, apply the
command gqap which applies the normal mode command gq to 'a paragraph'.
You might also want to capitalise the first word and increase the header level
of all the markdown headings like so:
:%g/^#/norm w~I#
This would change this:
# a heading
some text.
## another heading
some more text
```sh
# and a comment in some code will be unaffected
print('hello world')
```
## a further heading
some text
# conclusion
into this:
## A heading
some text.
### Another heading
some more text
```sh
# and a comment in some code will be unaffected
print('hello world')
```
### A further heading
some text
## Conclusion
see these videos for 'advanced' vim stuff
I'd implement this as an :s command. For example, this command would make the requested changes:
:%s/\.\(.*\),/['\1'],/
That operates on all lines %, matches the dot and comma and puts everything in between into a group (\(.*\)), and then replaces it with the desired value, matching the first group (\1).
If you want to operate on a different set of lines, you can write :1,4 instead of :%, or write :'<,'> to operate on the visual selection.

Vim: How to delete the same block of text over the whole file

I'm reviewing some logs with Java exception spam. The spam is getting is making it hard to see the other errors.
Is is possible in vim to select a block of text, using visual mode. Delete that block every place it occurs in the file.
If vim can't do it, I know silly question, vim can do everything. What other Unix tools might do it?
Sounds like you are looking for the :global command
:g/pattern/d
The :global command takes the form :g/{pat}/{cmd}. Read it as: run command, {cmd}, on every line matching pattern, {pat}.
You can even supply a range to the :delete (:d for short) command. examples:
:,+3d
:,/end_pattern/d
Put this togehter with the :global command and you can accomplish a bunch. e.g. :g/pat/,/end_pat/d
For more help see:
:h :g
:h :d
:h :range
Vim
To delete all matching lines:
:g/regex/d
To only delete the matches themselves:
:%s/regex//g
In either case, you can copy the visual selection to the command line by yanking it and then inserting it with <C-r>". For example, if your cursor (|) is positioned as follows:
hello wo|rld
Then you can select world with viw, yank the selection with y, and then :g/<C-r>"/d.
sed
To delete all matching lines:
$ sed '/regex/d' file
To only delete the matches themselves:
$ sed 's/regex//g' file
grep
To delete all matching lines:
$ grep -v 'regex' file
grep only operates line-wise, so it's not possible to only delete matches within lines.
you can try this in vim
:g/yourText/ d
Based on our discussion in the comments, I guess a "block" means several complete lines. If the first and last lines are distinctive, then the method you gave in the comments should work. (By "distinctive" I mean that there is no danger that these lines occur anywhere else in your log file.)
For simplifications, I would use "ay$ to yank the first line into register a and "by$ to yank the last line into register b instead of using Visual mode. (I was going to suggest "ayy and "byy, but that wold capture the newlines)
To be on the safe side, I would anchor the patterns: /^{text}$/ just in case the log file contains a line like "Note that {text} marks the start of the Java exception." On the command line, I would use <C-R>a and <C-R>b to paste in the contents of the two registers, as you suggested.
:g/^<C-R>a$/,/^<C-R>b$/d
What if the yanked text includes characters with special meaning for search patterns? To be on the really safe side, I would use the \V (very non-magic) modifier and escape any slashes and backslashes:
:g/\V\^<C-R>=escape(#a, '/\')<CR>\$/,/\V\^<C-R>=escape(#b, '/\')<CR>\$/d
Note that <C-R>= puts you on a fresh command line, and you return to the main one with <CR>.
It is too bad that \V was not available when matchit was written. It has to deal with text from the buffer in a search pattern, much like this.

VIM: Change current highlighted search term matched with /search

Is there any command equivalent to "delete until the end of the current highlighted search match and enter insert mode"?
For example, I search for a term with:
/Element
It finds the string ExampleElementExample, places the cursor on the E in Element, and highlights Element.
I would like a generic command that applies to all searches that is equivalent to c7l or ctE in this particular case. However, I also want to be able to easily repeat this command to the next match by pressing n, ..
c//e basically does what I want, but falls short because it replaces the current search buffer, so n no longer takes me to the next match. Right now I'm using ctE or visual mode, but I feel like there must be a better option.
What is the fastest and most efficient way to execute this command?
If your Vim is recent enough (7.3 with a patch-level above 6xx), you can use gn:
barbazfoobazbar
/foo<CR>
barbaz[foo]bazbar
cgnvim<CR>
barbazvimbazbar
You can hit . to jump to the next foo and change it to vim in one go.
See :help gn.
I think the best option would be to use search and replace with the confirm flag.
:%s//replace/gc
If you leave the search string empty, it will automatically use the current search string. By the c flag, it asks you for permission to replace and upon decision, it will move to the next match. The g flag will find all matches, not just the first on a line, which I hope is what you are looking for.
You can use the following custom text object taken from Copy or change search hit on the Vim Tips Wiki:
" Make a simple "search" text object.
vnoremap <silent> s //e<C-r>=&selection=='exclusive'?'+1':''<CR><CR>
\:<C-u>call histdel('search',-1)<Bar>let #/=histget('search',-1)<CR>gv
omap s :normal vs<CR>

Vim - Find pattern on currently line ONLY

I'm wondering if there is a way to find a pattern, but restrict it to the current line. Basically, the equivalent of /PATTERN but restricted to the current line, rather than the entire document.
I've tried :s/PATTERN, but that deletes the pattern from the line and places my cursor at the beginning of the line, which is not at all what I need. I was hoping you could search without replacing...
I'm hoping to use this for a macro in order to place my cursor at the start of that pattern, as would happen when you do /PATTERN on the entire file, so anything that is macro-friendly is even better.
Any vim users out there that might have an idea?
EDIT: 0/PATTERN in a macro would work for my current need, but I'm hoping there's a more specific way to restrict the search.
ANSWER: There's a few ways posted in here so far, but the one I like best right now is using Shift+V to select the current line visually, followed by /\%V to search only in the visual selection. Then Shift+V again will turn off the visual mode.
My knowledge about macro is limited, but interactively, you can select current line with Shift + V, and then do /\%Vsearch (see http://vimdoc.sourceforge.net/htmldoc/pattern.html#/\%V).
try to Find first character of the Pattern by typing
f <letter>
It's not exactly what you need but can help to solve the problem.
/\%9lsearch
Where \%9 means line number 9.
Typing in the line number is still a bit lame. You can ctrl+r= followed by a vim expression and enter to evaluate the vim expression and insert its output. line('.') will return the line of the cursor.
In one complete step
/\%<c-r>=line('.')<cr>lsearch
For more help see:
:h /\%l
:h i_CTRL-R
Place the cursor on the line you want to search in
Select it with shift+v
Type / to begin searching
Prefix your term with \%V, e.g. \%Vabc to search for abc in only the visually selected blocks (in our case the single line)
You can search without replacing by using
:s/PATTERN//gc
Then press n to skip the replacement. If the pattern is not found, you won't even be asked.
You could also just highlight the current line or the range of lines.

How can I insert text in the middle of the line to multiple lines in Vim?

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.

Resources