How to fix Home and End in Vim? - vim

I'm using vim in gnome-terminal (2.26.0): although I use 95% of the time "$" to navigate to the EOL and "0" for the opposite, every now and then I hit "Home" or "End".
When I use Home, the text I have in the current line is moved on line down, leaving me in insert mode in the current line and the letter H appears at the beginning of the line.
When I hit End, it's the same but with an F instead of H.
Why does it happen? How can I fix it? (fixing would mean to have the standard functionality when hitting these keys).

This happens because pressing the home and end keys in a terminal sends an escape sequence consisting of several characters to vim, and vim isn't correctly associating these escape sequences back with the keys you pressed.
To fix this you need to adjust the term setting. Gnome-terminal is xterm compatible, so you could try adding this to your .vimrc:
set term=xterm-256color
The term setting is derived from the TERM environment variable, so you might want to investigate why it isn't set correctly in the first place.

Related

How to use vim autowrap correctly?

I am trying to use the vim autowrap functionality to automatically wrap my paragraph into lines no longer than 80 letters in real time as I type. This can be done by set textwidth=80 and set fo+=a. The a option of the vim formatoptions or fo basically tells vim to wrap the entire paragraph while typing.
However, there is a very annoying side-effect, that I can no longer break a line by simply pressing enter.
This is a sample sentence.
Say for the above sentence, if I want to make it into:
This is
a sample sentence.
Usually I can just move the cursor to "a" and enter insert mode and then press enter. But after set fo+=a, nothing will happen when I press enter in the insert mode at "a". One thing I do notice is that if there is no space between "is" and "a", pressing enter will insert a space. But nothing else will happen after that.
So what do I miss here? How do I stop this annoying behavior?
You can run :help fo-table to see explanations of the options:
a Automatic formatting of paragraphs. Every time text is inserted or
deleted the paragraph will be reformatted. See |auto-format|.
When the 'c' flag is present this only happens for recognized
comments.
This means that every time you insert a character, vim will try and autoformat the paragraph. This will cause it to move everything back onto the same line.
I don't think you need to add a at all. I use neovim, but the behavior here should be the same. The default values are, according to the help pages:
(default: "tcqj", Vi default: "vt")
Try removing set fo+=a entirely from your .vimrc. Keep set textwidth=80. That should fix your issue.
EDIT: Once you have set textwidth=80, if you want to format an existing paragraph, you can highlight it in visual selection and press gq.
The following allows me to use the enter key to start a new line while setting the text width to be 79 characters:
set tw=79 "width of document
set fo=cqt
set wm=0 "# margin from right window border
After some exploration, I find a workaround that can solve the problem to some extent, though not perfect.
The basic idea is that when entering a line break, disable the auto-wrapping temporarily when sending <CR> and resume auto-wrapping after that. There are multiple ways of doing that. And the best one as far as I know is using the paste mode, since you don't have to exit insert mode when entering paste mode. So just make the following commands into any key binding you like in insert mode. The one I am using right now is inoremap <C-N> <F2><CR><F2>
The reason why I think this one is not optimal is that for some reason I cannot bind <Enter> in this way, but have to use another key.
If <Enter> or <CR> can be configured in this way then the problem is 100% solved.

Hide invisible unicode character

I don't know why but vim shows invisible unicode characters with space. Just enter this in vim and you'll see.
:tabe
:call setline(1, "\u2063hello")
There is a space after "hello". How can I hide this space? Or is there a way how I can mark text in vim with something invisible? For instance, there is a text in file
foo foo and I want to highlight first "foo". At this moment I mark first "foo" with "\u2063" character \u2063foo foo.
⁣hello
What you see depends on the terminal you're running Vim in. In GVIM (where Vim itself does the rendering), there indeed is an empty display cell at the beginning of the line. As Vim uses fixed, cell-based character addressing, this is expected. The U+2063 character is an invisible separator, but it still takes up one display cell.
Now, the terminal (I'm using Gnome Terminal) renders this character in a different way: It doesn't output anything. So Vim assumes the first cell has been occupied, and the h' of hello will be output at the second cell, but the terminal keeps the drawing cursor at the first cell, and all subsequent characters are rendered wrong. You can see the mismatch by moving around and using the ga command inside Vim.
Similar effects can be experienced with some combining characters, and other "funny" Unicode characters. I'm not sure whether the problem is with the terminal, Vim, or a mismatch in the interpretation of the terminal database.

Vim: Select all without scrolling away

is it possible in vim to select all lines in the current file, but leave the position where my cursor is unchanged?
Let's say I am currently at line 500 (of 3000) and want to quickly select everything (not yank), as my selection is simply set up to show whitespace characters. Can this be done without leaving my current line?
To achieve exactly what you like, you can press the following:
ggVG<Esc><Ctrl-O><Ctrl-O>
gg moves to the beginning of the file
V starts visual line mode
G moves to the and of the file (now you have selected the whole
file)
<Esc> leaves visual mode
<Ctrl-O> moves your cursor back to the prevois location (first to the beginning of the file, then the second time to your last position before pressing gg)
And if you like to select only the visible lines in you window (to not scroll away). You can use HVL instead of ggVG (H moves to the top of your window and L to the bottom).
You also could show whitespaces without using visual selection with something like this in your .vimrc:
set list listchars=tab:»·,trail:·,nbsp:·
This helps me to detect trailing whitespaces, and mixed (spaces/tabs) indentation.
usually pressing
ggVG
in normal mode will select all the lines, but it will leave your cursor at the last line of the file.
If you wants to highlights the whitespace characters then you can highlight this by using the below command in command mode (this white color chosen is for dark theme)
: hi ExtraWhitespace ctermbg=White guibg=White
Depending on what you are trying to achieve you can use something like :
%cmd
To apply the command to the whole file.
For example, %y will yank the whole file, %=will format the whole file, without moving your cursor. It does not really work if you do something like %d...
It is not a real selection though but rather a way to apply a command on the whole file.
To go further you can use something like
%norm Atest
To add 'test' at the end of each line. (Actually this is a bad example, because this command will move to the last line...)
It is not possible to have the cursor inside a visual selection. This caused by that, vim defines visual selection through two marks. As soon as you move the cursor one of the marks gets updated. Basically this means one of the marks is always lays where the cursor is(at least when using "v" to select). You cannot have the border in the middle of the region that the border defines :)

Vim commands containing `r` cause me to replace

I'm using vim and the python-mode extension, but I'm having a hard time using commands that contain r. It's causing vim to replace characters instead of executing my desired command.
Here is what the vim docs for python-mode say -
let g:pymode_rope_organize_imports_bind = '<C-c>ro'
So I'm doing CTRL-cro, but like I said, it's replacing which ever character I'm under with the letter o.
What am I missing?
It seems that your mapping is not being interpreted by Vim, so it only sees the Ctrl-c, which by default aborts the current action, then the replace command r (see :help r) followed by its "argument".
You could check if the mapping is defined with :map <c-c>.
If it is correctly defined it may be that your terminal is handling the Ctrl-c directly and not passing it to Vim, as stated in Vim FAQ 20.5 - Why does mapping the key not work?. In this case you could follow the instructions on Vim FAQ 20.4 - I am not able to create a mapping for the key. What is wrong?, in special:
1) First make sure, the key is passed correctly to Vim. To determine if
this is the case, put Vim in Insert mode and then hit Ctrl-V (or
Ctrl-Q if your Ctrl-V is remapped to the paste operation (e.g. on
Windows if you are using the mswin.vim script file) followed by your
key.
If nothing appears in the buffer (and assuming that you have
'showcmd' on, ^V remains displayed near the bottom right of the Vim
screen), then Vim doesn't get your key correctly and there is nothing
to be done, other than selecting a different key for your mapping or
using GVim, which should recognise the key correctly.

Change delimiters for navigating word-wise

When programming/writing I heavily use word-wise commands, for example "move to the left/right by one word", "delete next/last word" by pressing Ctrl (+left,backspace...).
The problem I have is, when the text I am editing contains symbols which will not be recognized as words, therefore ctrl + right will jump over a sequence of symbols AND a regular word after that.
Ideally I want to be able to set the delimiting characters for word-wise operations to space, tab, newline and opening and closing brackets - maybe also arithmetic operators (similar to how Eclipse handles it).
I am using Linux. Do you know any way how to change my settings system-wide or alternatively for xterm and (g)vim individually to achieve this?
Most likely, system-wide won't work. VIM is easy, you can set the characters that define the identifier using the iskeyword setting. In your case, there is too much in it, and you need to remove the ones you do need, or redefine it by adding the ones you do want. eg: :set isk=9,32,50-51
This will set keyword detection to spaces, tabs and parentheses.
However, in VIM you can jump based on word and WORDs, where the first is defined by the abovementioned iskeyword setting, while the latter will jump over all non-blank characters. Maybe, that's the motion you want. You can read more about this in the help (:help w).
Instead of holding down the control key and pressing the left/right cursor keys, why not use Vim's normal mode word motion commands?
w/W - move to start of next word/WORD
e/E - move to end of next word/WORD
b/B - move to beginning of previous word/WORD
ge/gE - move to end of previous word/WORD
You can read up on the difference between a word and a WORD by running :help word.

Resources