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.
Related
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.
I'm trying to make a transition to emacs (using evil mode/vim keybindings) and I'm having a hard time feeling more efficient/productive than if I just used the mouse. Here is an example of a situation where I find myself really slow:
for i in range(self.allData.shape[0]):
self.correctSequence = self.displayNumbers(i, self.allData)
self.userSequence = self.numberEntry()
self.allData.set_value(i, 'userSequence', ''.join(self.userSequence))
if len(self.correctSequence) != len(self.userSequence):
self.allData.set_value(i, 'correct', 0)
else:
if list(reversed(self.correctSequence)) == self.userSequence:
self.allData.set_value(i, 'correct', 1)
else:
self.allData.set_value(i, 'correct', 0)
It would be very common for me to have to change the first 4 instances of self.allData to something else (self.testData, for example), leaving the last 2 untouched.
Normally this wouldnt be too bad with a mouse. For example, I could replace the first allData with testData, copy it, use the mouse to the next 3 occurences and just hit CTRL-V for each one. Or better yet, just use multiple cursors in sublime/atom and replace all 4 in one go
I use spacesmacs in emacs with vim keybindings. So, in emacs I find myself having to do something like the following:
SPC-SPC a (avy jump to words beginning with a)
cw testData
Repeat those 2 steps once for each word I want to replace
This seems really inefficient and I'm wondering: am I just using an inefficient method? Is there a faster way to do what I want?
It seems that even if I managed to complete those steps really fast (4 times), theres still A LOT more typing one would have to do, and I fail to see how this would be faster than just reaching for the mouse. Yes, one could make the argument that I'm losing time by constantly reaching for the mouse, but in my mind I'm saving typing time by reaching for the mouse because I can just hit CTRL-V a few times to achieve what I want. Where exactly are the vim speed gains in a situation like this?
If you just want to replace, you can use query-replace, and replace the word one by one.
You can use replace-string too, but remember to limit replacement to part of the buffer, activate the region around that part.
Anyway, these commands could prevent you from finding the word by your eyes, moving cursor by mouse and moving your hand back to keybaord. And they could avoid probable overlook too. At least I don't want to leave my hands from the keyboard when typing. :)
I'm not sure how "vim-like" Spacemacs is, but you could do it like this in Vim:
/all<CR>
cgntest<Esc>
.
.
.
or:
/all<CR>
cetestData<Esc>
n.
n.
n.
or:
:,$s/allD/testD/gc<CR>
Maybe one of these methods works in Spacemacs too?
In addition to the usual (and generally the best) answer, query-replace (see #songyuanyao's answer), you can use the secondary selection to advantage to selectively paste the same thing at various places. Unlike the region, the secondary selection is unrelated to the cursor position (aka point), so it is always available regardless of where the cursor is.
And unlike query-replacing, you can paste it on demand, instead of having to answer for each matching occurrence. If you use delete-selection mode then just select some text to replace and paste the secondary selection to replace it.
You can set and paste the secondary selection using the mouse - see Secondary Selection on the Emacs Wiki, and see the Emacs manual, node Secondary Selection.
If you use library second-sel.el then you can use the secondary selection from the keyboard as well, and get a lot more use out of it.
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'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?
I've been using Vim for many years and have never really thought about it. A friend of mine asked why that is, noting that in our culture, left would usually map to up while right would map to down, making the Vim keys backwards.
I understand that they are on the home row, meaning that you do not have to move your fingers anywhere to hit them, but that's a different point altogether.
Why were these keys given their present purposes? Is there some documentation on the decision as well?
The answer is in the Wikipedia entry for vi. Bill Joy, who wrote the visual mode of ex - which ended up being Vim's precursor vi - used a Lear Siegler ADM-3A terminal on which the HJKL keys mapped to left, down, up, right - and it’s been that way ever since.
Here's the keyboard layout:
A couple of other points of note on the ADM-3A layout:
Left of the Q: the escape key - somewhat handier than where it is on keyboards today, hence a good choice for switching between normal and insert modes.
Top right: the 'Home' key doubles as the tilde (~), which subsequently became shorthand for a Unix user's home directory.
vimtutor provides the mnemonic that 'J' looks vaguely like a downward-pointing arrow, though that may or may not be the original reason why it was chosen.
This is a total guess, but: The Ctrl+J character is the "line feed" character, which on a traditional TTY moves down one line, providing a mnemonic. K was right next to it on a Qwerty keyboard, under the second most commonly used finger on the right hand when in the home position.
Simply to supplement all the answers, here is the photo of the ADM-3A keyboard (the exact keyboard on which Vim has been created).
P.S: I wish they had used W, A, S, D
From a user experience perspective, after you open a file, you always move down first and moving down is usually a more frequent operation. Since from left to right is the natural direction for most of us, it make sense to associate the task you perform first or more frequently with the key on the left. You can try to switch the 2 keys and try to tell which way is better. For me, "J" for down is more natural and comfortable.
It explains it if you run vimtutor in the terminal. It says:
The h key is at the left and moves left.
The l key is at the right and moves right.
The j key looks like a down arrow.
I always thought it was because on the Dvorak layout, j and k are also next to each other. There are not many keys that have this property on both Dvorak and A/QWERTY/Z.