I'm using Vim's surround and repeat plugins to wrap lines of text with html tags.
I'll use "yse<p>" and "ys$<p>", they both work fine.
I try to repeat the command with ".", and it shows <p> in the terminal, but whenever I press enter to execute the command, surround replaces what should be <p> and </p> with ^M.
My line looks like ^Mtext here^M
I recognize the character as a line ending, but I don't understand why surround won't wrap my line with the code it shows in the terminal (which is correct), but instead wraps my line with DOS line endings.
I'm using gVIM on windows XP, if that makes any difference.
surround.vim's documentation says:
The "." command will work with ds, cs, and yss if you install repeat.vim, vimscript #2136.
So if you are using yss it should work, but apparently other versions of "ys" aren't supported. Sounds like a good feature require to submit to the repeat.vim owner.
It's actually because <p> isn't really there when you repeat the command with .
Try this: Before you repeat the command with . first hit o to empty the command line area of any text, then hit .
You'll see that it is actually blank, which is why the cursor is on the first character.
To repeat the wrapping properly, you'll either have to type in <p> every time or record a quick macro.
Macro: ys$<p>
Paste that into vim, highlight it, and type "py
Now you can run the macro with #p
Related
In Vim I need to convert all lowercase to uppercase and all uppercase to lowercase with a single command. So if my text file looks like this..
Hello World
.. it needs to be toggled to look like this..
hELLO wORLD
I know :%s/[a-z]/\U&/g will change all lowercase to uppercase and that :%s/[A-Z]/\L&/g will change all uppercase to lowercase. But how would I write that to do both at the same time?
In addition I know if my cursor is at the top of the file VG~ will toggle case everything but that's not the answer I need. Thank you.
<Esc>1GVG~
Explanation:
<Esc> — return to Normal mode; just in case we're in Insert mode or Command line
1G — jump to the 1st line
V — start Visual mode
G — jump to the last line extending selection
~ — toggle case in the selection
Or
<Esc>1Gg~G
g~<motion> — change case during motion; the motion is G (jump to last line)
Docs: http://vimdoc.sourceforge.net/htmldoc/change.html#~
Looks like you already know everything you need. ggVG~ marks all your code and toggles the case. If you want a single command you can either use:
:nnoremap <keybinding> ggVG~
or use this function, which does the same, but keeps your current position in the file:
function ToggleCase()
exec "normal! mqHmw"
exec "normal! ggVG~"
exec "normal! 'wzt`q"
endfunction
command ToggleCase silent call ToggleCase()
the first and last exec mark your position in the file and restore them, after the case toggling. See: :h marks
type :ToggleCase to use the function. Of cause you can bind this to a keybinding as well.
:nnoremap <keybinding> :ToggleCase<cr>
Since you mentioned using a single command and you mentioned some :%s/.../ substitutions, I'll offer this one:
:%normal! g~~
This will run the g~~ command to switch case of a single line, for each line of the buffer.
One more way to accomplish this, if you're ok adopting a plug-in, is to use the kana/vim-textobj-entire plug-in for a text object for the entire buffer.
As the plug-in README.md file says:
Though these are trivial operations (e.g. ggVG), text object versions are more handy, because you do not have to be conscious of the cursor position (e.g. vae).
With this plug-in installed and enabled, you can switch case of the whole buffer with:
g~ae
Let's say you're browsing this page and you see the following snippet of code:
_trackEvent(category, action, opt_label, opt_value, opt_noninteraction)
You double-click to select the whole line, copy it and then want to insert it between the double quotes here in Vim:
<div onClick=""></div>
Well, instead of this:
<div onClick="_trackEvent(category, action, opt_label, opt_value, opt_noninteraction)"></div>
This is what I get when I do it:
_trackEvent(category, action, opt_label, opt_value, opt_noninteraction)
<div onClick=""></div>
And it's pretty annoying. It's due to the ending line break that's inserted by OS X in the clipboard. How could I tell Vim to ignore the ending line breaks when working with one liners?
Because you've copied an entire line (with a trailing newline), Vim uses linewise paste, i.e. the text isn't inserted at the cursor position, but in a separate line above / below the current one. With <C-R>* from insert mode, you can avoid that, but it will still insert the trailing newline.
My UnconditionalPaste plugin has a gcp mapping that pastes the register always in characterwise mode. (And several related mappings for other modes and special pastes.) With it, you just position the cursor on the first / second " and do "*gcp / "*gcP.
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.
Which is the shortest way to select an entire line without the new line character in VIM?
I know that SHIFT + v selects the entire line, but with new line character.
To do this I go to the line and I press:
^ (puts the cursor at the start of the line)
v (starts the visual select)
$ (selects the entire line including new line character)
Left (unselects the new line character)
I also know that I can create a recording that does such a thing. But I am asking if is there any built-in shortcuts...
Yes, g_ is what you are looking for. g_ is like $, but without the newline character at the end.
Use 0vg_ or ^vg_, depending if you want to copy from the beginning of the line, or the first character on the line, respectively.
No, there is nothing built-in that does the job. That's why people have even created plugins to address the need.
Probably the most popular choice is textobj-line. With textobj-line you get two new text objects, al "a line" and il "inner line". Then,
vil selects the printable contents of the line (like ^vg_),
val selects the entire line contents (like 0v$h).
Both do not include the newline in the selection.
Pretty handy plugin if you ask me. And it works with operators, too.
By request, the installation:
With plain Vim:
Get the latest textobj-user and extract its directories into ~/.vim.
Get the latest textobj-line and extract its directories into ~/.vim.
Generate the help tags :helptags ~/.vim/doc.
With a plugin manager (recommended): just follow the usual installation procedure for your plugin manager, and don't forget to install the textobj-user dependency as well.
0v$
^v$
0vg_
^vg_
$v0
$v^
g_v0
g_v^
all do the job with different conceptions of what a line is (from first column or from first printable character, to last character or to last printable character). You can create a custom mapping if you like.
Note that selecting text is often unnecessary in vim.
Adding on to the answer by #glts, you can replicate the functionality of the textobj-line plugin using only vanilla vim mappings, no plugin installation required.
To do so, add the following to your .vimrc
vnoremap al :<C-U>normal 0v$h<CR>
omap al :normal val<CR>
vnoremap il :<C-U>normal ^vg_<CR>
omap il :normal vil<CR>
The al text object (short for 'a line') includes all characters in a line, but not the terminating newline. This includes all white space.
The il text object (short for 'inside line') goes from the first non-blank character to the last non-blank character.
Commands such as yil,val, and cil work as expected.
If you want to copy line into the buffer, you can use Du, which will delete from the cursor position to the end of line with D, and then revert changes with u. Text will be copied to the buffer without new line symbol.
Redefine $ for visual mode
The unwanted selection of the linefeed in visual mode can be permanently eliminated by adding the following visual mapping to .vimrc:
vnoremap $ g_
This replaces the standard behaviour of $ in visual mode for the move towards right before the linefeed g_.
You can still a mapping to what you want, e.g.:
nnoremap <leader>v 0v$
Another solution $ will be working as you want it to
:vnoremap $ $h
maps your original $ command to new one
Not exactly an answer to your question, but I wonder if you can skip selecting the line and do directly what you want next:
If you want to change the line, just cc
If you want to yank the line, 0y$ (note $ here does not capture the line break because it does not move over it in normal mode, unlike in visual mode)
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