How to move to a certain character from right to left of line in Vim [duplicate] - vim

This question already has answers here:
Vim - Delete til last occurrence of character in line
(5 answers)
Closed 8 years ago.
This is a sentence
If the cursor is on s of This, I want to move the cursor on n of sentence
I can do $Fn
But this can't be used combining with other command like delete
e.g If the cursor is on s of This, and delete all between cursor and n of sentence
d$Fn doesn't work
Anyone knows how to do this?

Assume that you have trouble with deleting words between s and the second n in "sentence". You can do it by
d2fn
And as #kev mentioned, easymotion is a good choice, with easymotion you can do it in a more intuitive way like
d<Leader><Leader>fn
the above command will highlight n in the line and let you choose.

My JumpToLastOccurrence plugin extends the built-in f/F/t/T motions with counterparts that move to the last occurrence of {char} in the line. Your example would be d,fn.

Vim plugin easymotion can help you.

As others have said, you can use the search command / in combination with the d command to delete up to a pattern match.
But, you can also make use of search offsets to place the cursor anywhere you want in relation to that search. See :help search-offset for details, but in your case:
d/senten/e will delete up to and including the second 'n' in "sentence".
You could also use d/sentence/e-2 to do the same thing but limit the match even more.
This is very powerful in combination with incremental search and search highlighting, because then you can see exactly what you're acting on before you hit <Enter> to finish the command, or <Esc> or <C-C> to cancel the whole thing.

You could use visual mode: v$Fnd

My Vim plugin ft_improved can also help. You simply keep on typing until the match is unique.

I don’t know which “n” in “sentence” is referred to here, but you can indeed use d to do this. Simply combine it with search (/):
d/n
Or, if you want to delete up to the second “n” in “sentence”, you could make the search pattern one character more specific:
d/nc

Related

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.

Vim - Search and replace the results

I'm getting more and more comfortable with Vim after a few months.
BUT, there is only one simple feature I can't get any answer from the web. That is "Search and replace the results". The problem is that I know:
:/keyword to search, and hit enter "keyword" will be highlighted (of course with set hlsearch)
n, or N to navigate
:% s/keyword/new_keyword/g to replace all occurences of keyword with new_keyword.
BUT, I would think that there must be a way to search, and replace the matched keyword (highlighted) with any new_keyword WITHOUT doing ":% s/keyword/new_keyword/g", which is a lot of typing considering search & replace is such a day-to-day feature.
Any answers/comments will be greatly appreciated!
If you've already done a search you can do a substitution for the same pattern by simply leaving out the pattern in the substitute command. eg:
/keyword
searchs for "keyword", and then:
:%s//new_keyword/g
will replace all occurrences of "keyword" with "new_keyword".
Searching and using the dot command (you didn't meantion you are using the dot command, that's why I highlight it) to repeat the last input action is my best bet here.
I use s///g for search and replace.
Well, since #keyword# and #new_keyword# account for most of the characters, and you need some way to differentiate between them (i.e., a character in vim, or tab between entry fields in dialog in a different editor), you're left with maybe four or five keystrokes beyond that.
So I think you're probably overestimating number of keystrokes and also forgetting that (1) it becomes very natural, and (2) working this way allows you also to naturally modify the action performed by specifying a different range or option flag.
But you can cut down on keystrokes. If you want you can map a key to automatically bring up the command line with '%s/' already in place. e.g.:
nmap s :%s/
The command above would remap 's' (I'm not recommending remapping to that key, but it gives the idea) and set you up to insert the keyword.
Also, you can set the 'gdefault' option to default to substituting multiple times per line. This lets you skip the ending '/g' in your keystrokes:
set gdefault
See ':h gdefault' for help section on that option.
In the end I would say just get used to the default way it works, because using it that way allows you to keep same basic operation when you want to specify different ranges or option flags, and creating a new special map is just another thing to remember. gdefault may be worth setting if you think you're going to want it majority of time, adding /g flag at end when gdefault is set has effect of turning /g off. . .
Move to the first highlighted word then record a macro for replacing the word and moving to the next one, e.g:
gg
n
qq
caw new_word^[
n
q
#q
##
##
...

Vim copy and paste

My previous question seems to be a bit ambiguous, I will rephrase it:
I have a file like this:
copythis abc
replacethis1 xyz
qwerty replacethis2
hasfshd replacethis3 fslfs
And so on...
NOTE: replacethis1, replacethis2, replacethis3, ... could be any words
How do I replace "replacethis1","replacethis2","replacethis3",.. word by "copythis" word by using minimum vim commands.
One way I can do is by these steps:
delete "replacethis1","replacethis2","replacethis3",.. by using 'dw'
copy "copythis" using 'yw'
move cursor to where "replacethis1" was and do 'p'; move cursor to where "replacethis2" was and do 'p' and so on...
Is there a better way to do this in VIM (using less number of vim commands)?
Since you changed your question, I'd do it this way:
Move to the first "replacethis1" and type cw (change word), then type "copythis" manually.
Move to the next "replacethis", hit . (repeat last operation)
Move to the next "replacethis", hit .,
and so on, and so on.
If "copythis" is a small word, I think this is the best solution.
The digit needs to be included, and there could be more than one instance per line:
:%s/replacethis\d/copythis/g
Given that "replacethis[1-3]" can be arbitrary unrelated words, the quickest/simplest way to do this globally would be:
:%s/replacethis1\|replacethis2\|replacethis3/copythis/g
(Note that you need to use \| to get the pipes to function as "or". Otherwise, vim will look for the literal | character.)
I've been struggling with this for a long time too, I think I just worked out the cleanest way:
Use whichever command is cleanest to put copythis into register r:
/copythis
"rye
Then go to the replacement and replace it with the contents of r:
/replacethis
cw<CTRL-R>r<ESC>
Then you can just n.n.n.n.n.n.n. for the rest of them, or if they're wildly different just go to the beginning of each and hit .
The key is replacing and pasting in one step so you can use . later.
:%s/copythis/replacethis/g
To replace all occurrences of copythis with replacethis. Or you can specify a range of line numbers like:
:8,10 s/copythis/replacethis/g
Note, the /g on the end will tell it to replace all occurrences. If you leave that off it will just do the first one.
create this mapping:
:map z cwcopythis^[
( ^[ is the escape character, you can type it in vim using Ctrl+V Ctrl+[ )
go to each word you want to replace and press z
if u need to do essentially the same action multiple times - swap 1st word of one line with second word of the next line, I say you could record a macro and call it whenever you need to
Have you tried string replacement?
%s/replacethis/copythis
A host of other parameters are possible to fine-tune the replacement. Dive into the Vim help for more details. Some more examples here.
You can remap e.g. the m key in normal mode to delete the word under the cursor and paste the buffer: :nnoremap m "_diwP.
Then you can just copy the desired word, move the cursor anywhere onto the to-be-replaced word and type m.
EDIT: Mapping to m is a bad idea since it is used to mark locations. But you can use e.g. ; anyway.

Vim split line command [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I insert a linebreak where the cursor is without entering into insert mode in Vim?
In vim, J joins the next line to the current line. Is there a similar one-key (or relatively short) command to split a line at a given cursor position? I know it be done with a simple macro, but it seems like if the J-command exists there should be a similar function. I've tried searching for it, but can't seem to find an answer.
rEnter while on whitespace will do it. That's two keystrokes.
I don't think that there is a single key command for this. The best you can do with stock vim is probably i Enter Esc.
My solution was to remap the K key since I never use the default action (look up the word under cursor with "man"), and my previous editor used Alt+j and Alt+k to join and split lines, respectively.
:nnoremap K i<CR><Esc>
This rolls those three annoying keystrokes into one.
There's probably a more sophisticated way to also eliminate any trailing whitespace, but I prefer to strip all trailing whitespace on write.
No. I've now read enough answers to conclude that there is no such command.
Easy answer:
Pressing 'Enter' while in insert will do it; but you're right, there oughtta be a key for it in command mode. I've wondered, too.
Since everyone has a favorite workaround, I will share mine. The assumption is that I will do anything to avoid having to reach for the Esc key.
ylprX ... where 'X' is the inserted character, which can even be a newline.
So, 'yl' is yank on char to the right, 'p' = paste the char, 'r' is replace that char; then you just type the new char. That's how much I hate using Escape.
(That was 'l', as in "move right", BTW)
Old thread, but I dont use "K" for the man page lookup or whatever magic it does. So I have this mapping in my .vimrc:
map K i<Enter><Esc>
I figured since "J" is join, "K" can be krack or something. :)
You can split lines if you can create a regular expression for the location to add the split. For example if you want to split the lines at each semicolon, you can use the following substitution:
%s/;/^v^m/g
to great effect
Jed's answer is most useful. I would like to add that I needed the "control-V-alternative", i.e. control-Q:
%s/;/^q^m/g

In vim, how do I go back to where I was before a search?

Programming in vim I often go search for something, yank it, then go back to where I was, insert it, modify it.
The problem is that after I search and find, I need to MANUALLY find my way back to where I was.
Is there an automatic way to go back to where I was when I initiated my last search?
Ctrl+O takes me to the previous location. Don't know about location before the search.
Edit: Also, `. will take you to the last change you made.
Use `` to jump back to the exact position you were in before you searched/jumped, or '' to jump back to the start of the line you were on before you searched/jumped.
I've always done by it setting a mark.
In command-mode, press m[letter]. For example, ma sets a mark at the current line using a as the mark identifier.
To get back to the mark press ' [letter]. For example, 'a takes you back to the line mark set in step 1. To get back to the column position of the row where you marked the line, use `a (back-tick [letter]).
To see all of the marks that currently set, type :marks.
On a slightly unrelated note, I just discovered another nifty thing about marks.
Let's say you jump to mark b by doing mb. Vim automatically sets the mark ' (that's a single-quote) to be whichever line you were on before jumping to mark b.
That means you can do 'b to jump to that mark, then do '' (2 single-quotes) to jump back to wherever you were before.
I discovered this accidentally using the :marks command, which shows a list of all marks.
You really should read :help jumplist it explains all of this very well.
CTRL+O and CTRL+I, for jumping back and forward.
I use this one:
nnoremap / ms/
nnoremap ? ms?
Then if I search something by using / or ?, I can go back quickly by `s. You could replace the letter s to any letter you like.
The simplest way is to set a mark, with m[letter], then go back to it with '[letter]

Resources