I've replaced my fFtT completely with EasyMotion's equivalent and I've found it to be adequate in most cases except when I need to repeat the last motion with text objects. For example, dot command following ct or cf don't work the way they're supposed to. Is there a way make this work somehow, or do I have to resort to mapping the original ftFT for cases like this?
I try to be bold, without testing and say, NO, it cannot be repeated.
you typed some magic key (for example, f . Default <leader><leader>f), triggered easyMotion, try to move to letter x. but on your current screen, there are 10 x after your cursor. Then you typed c to move to the right one. now you try to type dot . to repeat it. how easyMotion know which x you want to go to next?
Related
Edit: I moved this over to the Vi and Vim site: https://vi.stackexchange.com/questions/13689/how-to-find-and-replace-in-vim-without-having-to-type-the-original-word
I'd like to optimize my "find and replace" workflow in Vim. It's something I do often, as I'm sure most of you do too. Usually something along the lines of -- copy a block and change the name of a variable in a few places. I know, I know, that probably triggers your "why are you copying and pasting code" reflex, but let's not go down that road... There are plenty of valid use cases :)
I'm well aware of the search and replace commands: :s or :%s but I don't like them. It forces me to type out both the full variable name I'm searching for and what I'm changing it to. Maybe there is a better way fix the the amount of typing with :%s? I often use long descriptive variable names, so that is really a deal breaker for me. I also don't like how typing out a variable name from scratch is typo prone and can consume time and brainpower hunting down typos. I much prefer typing it once, and then copying and pasting to just avoid this entirely if possible.
My current workflow uses some combination of movement/yank/select/search/put to move around the file and replace one by one. It is not great but has the benefit of avoiding typing out full variable names. I might just need to type the first few letters with / or use another movement command (i.e. fx) depending on what's around and then hit ve to select the whole word. I also don't mind that I have to repeat for every instance. I never do a full find replace without confirming each change. But it would be much preferable if I could repeat the replacement action with a single keystroke (which I can't do with this method). each replacement is usually something like n then ve then p (or even worse "0p)
Is there a faster way?
My own workflow is similar to yours:
To start, get the cursor on one instance, possibly with / or by navigation.
Hit * to find the next instance of that word.
Change one instance with cw and then the new variable name.
Then it's fast: n/N to get to the next/previous instance, and . to repeat the last edit.
This workflow gives me the same advantage as yours, in that I can review each case before applying the change, but it's just two keystrokes for each additional change.
Hope this helps.
I like the "visual highlight then edit" approach.
shift + v to highlight the region that you want to modify.
then :s/old/new/r where old is what word you want to replace with new.
r changes the first instance of that word old.
Note* There are options other than r which modify its behavior how you want to replace the word.
Imagine you need to change a few last letters in a word.
From
.. visualizing a graph?_
(_ denotes where the cursor is, mode:normal)
you need to arrive at
.. visualize| a graph?
(| denotes the cursor, mode:insert)
How would you do this?
(please suggest how would you really do this, not the "super-doper" way nobody uses)
I am asking, because I do this insanely inefficiently:
type b until reach _visualizing a graph?,
followed by e (visualizinG a graph?),
followed by x to remove g under cursor,
followed by few Shift+x to remove what is before the cursor,
and, finally, i switch into the insert mode and type e.
With given example, I would do:
Tzcwe
If there are just a few words between the cursor and where I want to go, I will use CTRL+left as many times as needed plus CTRL+right once and <bs> 3 times. I may also use the mouse. It's not that different from what you use, except I don't leave the insert mode for simple moves. Note this is exactly what I use when I type messages in my browser (I've never been conquered by vimperator & co).
I'm aware of <esc>gegege...3<left>cwe<esc>. But that's definitively not my first choice.
I may use T and F on symbols with few occurrences, but I seldom use them on letters as I'll spend more time detecting the best character to use than using CTRL+cursor as many times as needed. Beside, when I'm correcting what I've typed, it's likely that my mind is in "reread+correct/refactor sentences" mode, speed typing is not my priority.
Imagine I have a sentence like this:
Block chain, the decentralised public ledger that records transactions on the bitcoin network.
And if my cursor is at the end of the first word, is there a way to move relative to the end of the sentence rather than from the cursor position? Think of something like, the first c from right hand side is where I want to go, is there a way to reach rather than going to the end first and using F to reach the c ($Fc).
Yes, Vim has (an abundance of) motions that move relative to the current (cursor) position: l, w, f among them. And you can re-position the cursor easily with many motions: ^, 0, $, gm. When combined, that means you can reach almost any place with just a few keystrokes, and it's possible to remember each of those quite easily.
Given that there's a limit to available keys (and that Vim out of the box already uses most of them!), and a limit to what you can memorize, I think that's a perfect balance. In that light, I think $Fc is nothing to worry about (just compare with other editors!)
If that particular motion's inefficiency bothers you, you can always write a custom mapping (and assign one of the few available keys), but that doesn't scale well.
If you think $Fc 3 keystrokes is too many......
operator + target char have already 2 strokes.
We can dynamic capture the target char. But to make it 2 strokes, we have to scarify a normal mode key, I don't know which one you don't use, I just cannot find one on my keyboard, so as example I use the <F6> you can change it as you like.
This mapping allows you press <F6>c to that place, of course, c could be any character.
nnoremap <expr> <space> '$F'. nr2char(getchar())
And this won't work if the target char, i.e (c) is at the EOL. Well you can do further checking, e.g. write your own function to do it, if you think it is really necessary.
Personally I don't think it is worthwhile. Just get used to the $Fx.
Let's say we're currently in this line of code:
readonly L|a|zy<ICountryRepository> countryRepo;
and the cursor is in the position of letter "a", as shown in the code between two "|" symbols.
Now I want to move my cursor to the letter y of the word countryRepo, how can I do that using the minimum key strokes?
(Currently I'm using the key sequence of fyfyfyfy in normal mode ... Kind of stupid)
If you know that it's the 4th y, you can do
4fy
If you know it's the last y in the line, you can do
$Fy
If you don't know at which position it is, you can still do
fy;;;
In this case, I would use
W
to move to countryRepo, followed by
fy
I can think of:
4fy
But you should only do this if you are some strange robot.
/co<cr>fy
Which is one character shorter than your solution, but more easy..
Wfy
Go one WORD forward and then find y.
f>fy
Something like this I would do. Depends on what popups in my mind.
You should look into the easymotion plugin, which helps with arbitrary movements.
EDIT:
easymotion is rather worthless here, it is more useful for jumping to targets further away.
If you have vim-easymotion, https://github.com/Lokaltog/vim-easymotion
You can do <leader><leader>t and then search for letter y. It's not that fast for the letters on the same line though. The real advantage is when you jump in the entire file.
I would do
tR;
or
WtR
or maybe
Wfy
Use EasyMotion.
In your case, <Leader><Leader>e then a corresponding keypress (in this case b) will bring your cursor onto the second y. Personally I use <Leader> as the easymotion trigger so it is only 3 keystrokes for me. The main advantage is you do not need to guess or calculate.
use / for search, then type your word and press Enter
however, if you want to jump to next word, just press n
I'm aware of the possibility to edit multiple lines on the same column by doing:
CTRL+V down...down..down... SHIFT+I type_string_wanted
But I'd like to edit multiple specific locals addin new strings (maybe using cursor (h j k l) or mouse (with :set mouse=a)).
Like on this example, where I want to add the string 'XX' to specific locations. I.e.,
from this:
Hi.
My name is Mario!
to this:
XXHi.
My XXname is XXMario!
Any ideas?
Edit the first location and then use . to repeat the action at each additional location.
I'd reverse the order of your steps.
Instead of marking each location, then performing the change on all at once, just edit the first location, then use . to do the same to each of the others.
This doesn't add any keystrokes to your use case; instead of hitting some key to mark a spot beforehand, you hit . afterward.
If you suspect you might accidentally do some other things in between usages, you could record a macro using q<register> the first time, and play it back with #<register> each of the others.