change specified line to uppercase in vim - vim

How to change the specified line to uppercase in vim?
For example,i want to change the lines from 5th till 10th to uppercase.
In ex mode ,5,10gU or 5,10gUU can't work.

You had the basic idea down with your ex command. But gU is a normal command, not an ex command. You can call a normal command with norm, so putting it together, you can do what you want with:
:5,10 norm gU$

Probably not the most efficient, but the following visual selection method works:
5ggV5jU

Shorter answer:
5G5VU
Alternate answers:
5GgU5j
5GgU10G

Related

In vim toggle case of all characters in a text file with a single command

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

Delete all characters after "." in each line

I have a text file with about 2,000 lines of text and I want to remove a large portion of each line of text.
The text is in this format:
Important Text that I care about. Stuff I want to delete
I am unsure as to how to delete all of the text after the . in each line.
Can someone give me a quick command that would do this?
With substitutions:
:%s/\..*/./
With :normal command:
:%norm f.lD
Various additional :normal solutions:
:%norm )Dx
:%norm $T.D
:%norm f.C.
:%norm 0/\. /e<C-v><CR>D
Use the Substitution Ex Command to Trim All Lines
This is very similar to both answers, yet I think there is value in presenting it.
Like the other answers, I just used the ex substitution command:
:%s/[^.]*$//
Explanation of substitution:
% indicates a range for all lines.
[^.] is a character class of all non-period characters
* is a quantifier indicating 0 or more matches.
$ is an anchor which communicates to VIM that we want this pattern to match at the end of the line.
Addendum
The solution assumes each line will have a period, otherwise the command will not work as expected as #Qeole has indicated. Qeole's solution addresses non-periods lines appropriately.
Use search and replace "vim feature" combined with regex:
:%s/\..*$//g
with the cursor at the first character of first line.
fS<Ctrl-V>G$d

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 does not replace the word after the dot punctuation. How to change it?

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

Yank first word from specific line

I figured out that :23y will yank the entire 23rd line.
But what I want to do is yank only the first word on line 23.
I tried :23yw, but that does not work. Is there an easy way to do this?
Can this be done without going to the line first and then yanking and then typing ` to go back to the line I was editing on?
23ggyw will do it. I don't think there's a quicker way.
Explanation: 23gg moves the cursor to line 23, yw yanks one word.
Note that this only works if you have the startofline option set (which is the default). Otherwise you need to explicitly move to to the first non-whitespace character: 23gg^yw.
The :y is an abbreviation of the :yank Ex command, that's why :yw does not work; it's a normal mode command. As the other answers have already shown, you can trigger those from the command line via :normal yw.
I'm afraid there's no way avoiding the jump in a practical way (but, as mentioned, <C-O> lets you jump back to the original position). You could use Vimscript:
:let #" = matchstr(getline(23), '^\w\+')
But that's hardly easier to type, and only suitable for a function.
I don't think there's a way to do that without moving the cursor.
Anyway, here is another way to do it:
:23norm! yw
Breakdown:
: because we are using an Ex command,
23 is the line on which we want to do something, it is a range of 1,
norm[al] executes a normal mode command on the given range,
yw yanks the first word.
Add <C-o> to go back to where you come from.
type 23Gyw in normal mode should do the job.
G Goto line [count], default last line, on the first
non-blank character |linewise|. If 'startofline' not
set, keep the same column.
G is a one of |jump-motions|.
Following would work without moving the cursor as requested but it's a hassle to type.
:23y|norm PJ0eld$
or you could try working out something with
:23t.|norm eld$
23jyw should be able to do it, it will take you to 23rd line and yank first word

Resources