Remap End Key - $ Not Sufficient - vim

I am trying to get off of using the arrow keys to navigate in VIM, so that I dont have to move my hands off the home rows. The problem I am having is finding the End Key equivalent. I used it a ton to go to the end of a line. I can still use it, but then I have to move my hands off the home rows, making this adjustment pointless. $ moves my cursor to the last character in the line, not after the last character in the line, which is where I want it to go. Why would I want to insert right before the last character on the line?
How can I remap the functionality of End Key (which can be used in insert and visual mode) to something else?
Thank you

It looks like you are doing $i which is the wrong approach.
$ is the right command to reach the end of the line but i is used to enter insert mode before the current character. You are supposed to use a to enter insert mode after the current character.
So you seem to be blocked because you don't know about a which is just as basic as i, IMO.
$a would solve your immediate problem.
But there's more, did you know that you can use I to enter insert mode at the beginning of the line? What command could we use to enter insert mode at the end of the line?
You are right, the correct command to enter insert mode at the end of the line is simply A, as #dusan commented.
You don't need to remap anything. What you need is a second (first?) injection of $ vimtutor.

Related

How to delete, including the current character?

Let's say I've typed "abcdefg", with the cursor at the end. I want to delete back to the c, so that I only have "abc" left.
Is there a command like d that includes the current character? I know I could do dTcx, but the x feels like a work-around and I suppose there's a better solution.
No. Backward motions always start on the left of the current character for c, y and d which is somehow logical but also unnerving.
The only "clean" solutions I could think of either imply moving to the char after c first and then do a forward delete:
Tcde
or using visual mode:
vTcd
v3hd
But, given your sample and assuming you are entering normal mode just for that correction, the whole thing sounds extremely wasteful to me.
What about staying in insert mode and simply doing ←←←←?
try this:
TcD
this will leave abc for your example... well if the abcdefg is the last word of the line.
if it is not the last word in that line, you may do:
ldTc
or golfing, do it within 3 key-stroke:
3Xx or l4X
See this answer to a similar question : there is a setting to be allowed to go beyond the end of the line
From the doc :
Virtual editing means that the cursor can be positioned where there is
no actual character. This can be halfway into a tab or beyond the end
of the line. Useful for selecting a rectangle in Visual mode and
editing a table.
"onemore" is not the same, it will only allow moving the cursor just
after the last character of the line. This makes some commands more
consistent. Previously the cursor was always past the end of the line
if the line was empty. But it is far from Vi compatible. It may also
break some plugins or Vim scripts. For example because |l| can move
the cursor after the last character. Use with care!
Using the $ command will move to the last character in the line, not
past it. This may actually move the cursor to the left!
The g$ command will move to the end of the screen line.
It doesn't make sense to combine "all" with "onemore", but you will
not get a warning for it.
In short, you could try :set virtualedit=onemore, and see if your environment is stable or not with it.
Use d?c
That will start d mode, search back to 'c' and then delete up to your cursor position.
Edit: nope, that does not include current position...
I may be misunderstanding your request, but does 3hd$ do it?
I would use vFdd in this example. I think it's nicer than the other solutions since the command explicitly shows what to delete. It includes the current character and the specified character when deleting.
v: enter visual mode (mark text)
F: find/goto character backwards
d: the character "d" that will be included for removal.
d: delete command
Since it is visual mode, the cursor can also be moved before executing the actual removal d. This makes the command powerful even for deleting up to a non unique character by first marking a special character close to the character and then adjusting the position.

vi to delete from the beginning of the line till the cursor

How can we use vim to delete characters from the beginning of the line till the cursor.
Say, we have a string "hello world" while the cursor is on "w". How can we delete from "h" till "w".
Try d0. 0 denotes the beginning of the line.
I believe that the following should work (d^):
d^
This assumes that you only want to delete to the h even if there is white space in front of it. It will leave the white space.
TLDR:
The easiest way is to do the following
use the navigate mode
set the cursor at whatever line you want
press dgg - this will remove everything from cursor to the beginning
press dG - this will remove all the lines from cursor till the end of the doc.
But why?
gg - goes to the begin of the document
G - navigates at its very end
d - delete mode
I was also looking for some combinations with the notation of d and line number, and when you are editing huge files like GB in size I found it bit annoying.
Like to remove first 3 lines you need to do this :0,d3, but when the docu is over 1mln lines its tough for my eyes to read this crap...
The other suggestions didn't work for me, but I used visual mode to achieve this.
I moved the cursor to the position I wanted to delete through, and hit v to enter visual mode. Then I hit ^ to select back to the beginning of the current line, and then d to delete all of the highlighted text.
If you're in insert mode and you want to delete to the start of the line (and stay in insert mode), you can use CTRL+u
This matches the bash meaning of CTRL+u as shown here.
I don't know if this is undocumented or just a quirk of my setup (neovim on Ubuntu) but doing :help CTRL-U shows the help for the keystroke out of insert mode. Maybe someone can help me find the help which points to the usage I'm describing here.
not sure what happened but when I enter the d0, the line got deleted from my
cursor location to start of the line. – YouAreAwesome Dec 14 '17 at 6:43
Confirming that this worked. It seems to be the simplest method. (You can't upvote a comment, so I'm adding it as an answer in it's own right.)
Example: In .ssh/authorized_keys, I had:
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user "centos" rather than the user "root".';echo;sleep 10" ssh-rsa AAAAB3NzaC1yc2...
This is the way Amazon AWS keeps you from logging in as root.
I put the cursor on the s in ssh-rsa and hit 'd0' and got a perfect delete to beginning of line.
Well, if your cursor is on "w", you'll be deleting backwards...
You can use vim's "till" t, but moving backwards it requires an uppercase T.
The same works for "find" f moving backwards it's F.
So, in your case, you can delete back "till" the quote symbol:
dT"
Or, if to prefer targeting/finding the "h":
dFh
Try jumping around first without the delete to get a feel for it, then you can just layer in the action as the prefix.
Happy Vimming! :)

Difference between append and insert mode in Vim

I noticed this accidentally when playing around in vimtutor. What's the difference between append and insert mode in Vim? When I type a in normal mode (not A) I can insert text. When should I use one and not the other?
The append command will put the cursor after the current position, while the insert command will put the cursor before it.
Using the append command is like moving the cursor one character to the right, and using the insert command.
Using the insert command is like moving the cursor one character to the left, and using the append command.
You choose which depending on where you want to start typing.
Note that vimtutor doesn't initially make the case of the command obvious:
SHIFT+A (capital A, as opposed to a) the cursor moves to the end of the current line.
SHIFT+I (capital I, as opposed to i)moves to the start of the current line.
Another important aspect on Append is that if the position after the current position is a empty space followed by a word. After you are done writing it will concatenate both words.
E.g. A file with the following text:
Hi there.
With the cursor on i. After pressing the a button and then ESC you would have:
Hithere.

How do I get fine-grained undo in Vim

I find Vim's undo to be a bit too coarse. E.g. if I type something like this:
a // to go into edit mode
to be or not to ve
<esc> // to exit insert mode
Oops! I made a typo. I want to start undoing so I press u, but then it clears the whole line. Is there a way to undo word-by-word or character-by-character?
You can break undos via :help i_ctrl-g_u. You can map this if you want for every character, but that might a little bit complicated. Mapping this to space button is a way.
:inoremap <Space> <Space><C-g>u
After that every word can be undo via u
So as you see from the others what you are asking for doesn't exist in Vi (AFAIK).
Undo undoes what your last action was. If your last action was to enter insert mode and then add a line and then exit insert mode. That will be undone, however if from the default mode you hit the "x" key then you will delete 1 character or if in visual mode with text selected the text will be deleted. If you hit undo then you will restore that one character or the text that was selected.
...You should think of this as an action, and actions can be atomically undone or restored
As mentioned previously if you wish to delete the previous word then you should be able to hit Ctrl + w and delete the previous word while remaining in insert mode.
If you exit insert mode you can navigate (motion) back a word with "b" forward a word with "w" to the end of a word with "e", and can cut (which leaves you in insert mode) with "c" or delete with "d". Both actions cut and delete can accept a motion following them so you can delete the current word / up to the next word with "dw" or cut the previous word with "cb"
This concept becomes more useful when you remember to use the "." command (in normal mode). This command is to repeat the last action. I have used this many times to find and replace a small group of words in a file (It is especially useful if you are paranoid about changing too much). The scenario would be the following:
File:
This is my post
really it is a test
this is the middle
This is the end
if I wanted to replace "is" with "was" I could write:
%s/\<is\>/was/g
however if I wanted to change the first line and the third line "is" to "was" (and I didn't know their line numbers, and I wanted to see if there were any other places I wanted to change is to was I could type
"/is"
hit "n" until I reach the place I want substituted, and then hit "cw" and type "was"
I can now hit "n" until I reach another place I want substituted and hit ".", and that will replace "is" with "was" (Note: my search string didn't limit to the word "is", just the two characters "is" so "This" & "this" will match in this case)
No, it is not possible and is actually not necessary either. Vim has a million ways of dealing with that. Try cb for example. Or bC. Or brb. Or Tspace to jump back instead of b. Or ciw.
You can, of course use most of these solutions in insert mode (by pressing CTRLo first), or bind one to your favorite key combination (:help map and :help imap).
On Linux, using control-w while in input mode deletes the last 'word'.

How to repeat a command with substitution in Vim?

In Unix the ^ allows you to repeat a command with some text substituted for new text. For example:
csh% grep "stuff" file1 >> Results
grep "stuff" file1
csh% ^file1^file2^
grep "stuff" file2
csh%
Is there a Vim equivalent? There are a lot of times I find myself editing minor things on the command line over and over again.
Specifically for subsitutions: use & to repeat your last substitution on the current line from normal mode.
To repeat for all lines, type :%&
q: to enter the command-line window (:help cmdwin).
You can edit and reuse previously entered ex-style commands in this window.
Once you hit :, you can type a couple characters and up-arrow, and it will character-match what you typed. e.g. type :set and it will climb back through your "sets". This also works for search - just type / and up-arrow. And /abc up-arrow will feed you matching search strings counterchronologically.
There are 2 ways.
You simply hit the . key to perform an exact replay of the very last command (other than movement). For example, I type cw then hello to change a word to "hello". After moving my cursor to a different word, I hit . to do it again.
For more advanced commands like a replace, after you have performed the substition, simply hit the : key then the ↑ up arrow key, and it fills your command line with the same command.
To repeat the previous substition on all lines with all of the same flags you can use the mapping g&.
If you have made a substitution in either normal mode :s/A/B/g (the current line) or visual mode :'<,>'s/A/B/g (lines included in the current selection) and you want to repeat that last substitution, you can:
Move to another line (normal mode) and simply press &, or if you like, :-&-<CR> (looks like :&), to affect the current line without highlighting, or
Highlight a range (visual mode) and press :-&-<CR> (looks like :'<,'>&) to affect the range of lines in the selection.
With my limited knowledge of Vim, this solves several problems. For one, the last visual substitution :'<,'>s/A/B/g is available as the last command (:-<UP>) from both normal and visual mode, but always produces an error from normal mode. (It still refers to the last selection from visual mode - not to the empty selection at the cursor like I assumed - and my example substitution exhausts every match in one pass.) Meanwhile, the last normal mode substitution starts with :s, not :'<,'>s, so you would need to modify it to use in visual mode. Finally, & is available directly from normal mode and so it accepts repetitions and other alternatives to selections, like 2& for the next two lines, and as user ruohola said, g& for the entire file.
In both versions, pressing : then & works as if you had pressed : and then retyped s/A/B/, so the mode you were in last time is irrelevant and only the current cursor line or selection determines the line(s) to be affected. (Note that the trailing flags like g are cleared too, but come next in this syntax too, as in :&g/: '<,'>&g. This is a mixed blessing in my opinion, as you can/must re-specify flags here, and standalone & doesn't seem to take flags at all. I must be missing something.)
I welcome suggestions and corrections. Most of this comes from experimentation just now so I'm sure there's a lot more to it, but hopefully it helps anyway.
Take a look at this: http://vim.wikia.com/wiki/Using_command-line_history for explanation.

Resources