One frustrating behavior in vim is that when i move my cursor right or left (respectively "l" or "h)" and i am at the end or the beginning of the line, my cursor doesn't move to first column of next line or last column of previous line.
Is there a way to change this behavior ?
You can use the whichwrap setting to make h and l wrap around the start and end of individual lines:
set whichwrap+=h,l
However, Vim's documentation recommends against this, probably because it could have unexpected side effects (like breaking plugins, or changing how common key mappings work).
As an alternative, you can do what what Matti Virkkunen recommended:
set whichwrap+=<,>,[,]
This leaves h and l with their default behavior, but allows the left and right arrow keys to wrap around lines. (This is what I do, and it works well.)
You might also want to take a look at the backspace setting, to control how Backspace, Delete, Control+W, and Control+U work in Insert mode. I set mine like this:
set backspace=indent,eol,start
That allows me to backspace over pretty much everything.
For more info, see these topics in the Vim help:
:help 'whichwrap
:help 'backspace
Put the following into your .vimrc:
set whichwrap+=<,>,[,]
Related
I fairly often find myself in a situation like this:
I'd like to start typing on the line on which my cursor is currently. However, in order to get to the correct indentation level, I'd have to press TAB several times.
Usually I'd press ddO (delete current line and insert a new one above the cursor), which resets my indentation position to the right place:
But that seems like an odd way to go about adding the correct amount of whitespace.
Is there a better way that I'm overlooking?
When in normal mode, you can use cc or its synonym S. If you are already in insert mode, Ctrlf is the default key for this, but that can be changed by altering cinkeys (see :h cink for details).
See also this answer on the Vi/Vim stack
Kevin mentioned some shortcuts, but another method is <C-i> (indent) and <C-d> (dedent) in insert mode.
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.
One tiny piece of functionality I find myself missing increasingly often is the ability to move vertically in a similar fashion to f and t. Usually what I want is to move to the top or bottom of a paragraph without losing my column position, and while I "could" just write a script for it, I wondered if there is any known way around this problem that you guys know of.
Example ( [ ] = current position, < > = destination ):
set tabstop=4
set shiftwidth=4
set <s>ofttabstop=4
set gfn=Source\ Code\ Pro:h14
set encoding=utf-8
set [t]_Co=256
set number
Like a vertical fs, or t<space>.
Again, this is usually useful when working with blocks of code. Any ideas?
vim regex provides \%nc (n is col idx) to match only in certain column.
so without installing plugin, what you could do is :
nnoremap <leader>f :<c-u>exe line('.').'/\%'.col('.').'c'.nr2char(getchar())<cr>
in this way, you press <leader>f, then press a key, vim will search that char in the same col. next, you press n/N
If you want to have the same but search backwards, use ?.
The most basic way is to use forward search, /t_<CR> and backward search, ?so<CR>, ideally with set incsearch.
But there are quite a lot of plugins designed around that idea:
EasyMotion,
Sneak,
Fanfingtastic,
and a few others…
For moving vertically without changing columns, you can use <n>j or <n>k. That doesn't completely help with "top of paragraph" or "bottom of paragraph" without counting the lines. There's also '{' and '}' for jumping between paragraphs. Not sure there's a single command to do exactly what you want...
I recently implemented the JumpToVerticalOccurrence plugin (just published), which implements an f{char} equivalent as ]V{char}. It also has related mappings that jump to the same character the cursor is under, or to non-whitespace in the same column.
I have a mapping that might be useful in visual selection.
To extend the selection downwards (<leader>j) or upwards (<leader>k) from the current column, but not beyond the block of text:
vnoremap <leader>j <Esc>m`:let b:ss=#/<CR>:let b:zz=col('.') - 1<CR>/\%<C-r>=b:zz<CR>c.\zs.\+\n.\{,<C-r>=b:zz<CR>}$<CR>:let #/=b:ss<CR><C-v>``o
vnoremap <leader>k <Esc>m`:let b:ss=#/<CR>:let b:zz=col('.') - 1<CR>?^.\{,<C-r>=b:zz<CR>}\n.*\%<C-r>=b:zz<CR>c.\zs.<CR>:let #/=b:ss<CR><C-v>``o
It also avoids clobbering the search register. At least, that's how I avoid clobbering the search register.
I am experiencing a weird problem: vim doesn't expand my foldings sometimes when I use a horizontal gesture like l. It always expands if I use zo though. I can see hor option in my foldopen settings variable. I am experiencing this when foldmethod is set either to indent or expr. What may I be missing? I don't seem to be mapping l anywhere.
Thanks
If you cursor is on an empty line inside the fold then the left move (l) will not work, thus it won't open the fold.
The same happens if your cursor is at the last column in the line. But in this case an h will make the fold open.
You can check if the a movement command fails by paying attention to the error beep, the same it issues when you hit Esc when you are in normal mode. If you are unable to hear it, you could try using the 'visualbell' option.
Using macvim, when I copy a text selection, it always includes the character under the cursor.
For example, if the cursor is at the far left and I press shift-down arrow, it selects the entire line plus the first character of the next line (since the cursor is sitting over the next line's first character).
Is there a way to configure macvim to not include the cursor character in text selections?
Take a look at the selection option. By default it's set to inclusive, but you can change it to exclusive to make text selections act the way you want:
:set selection=exclusive
You can also set it to exclusive with the behave command:
:behave mswin
This also sets several other options, however, which may or may not be what you want. See the Vim help for the specifics.
:help :behave
:help 'selection'
I am guessing that shift-down arrow activates visual character mode, and moves the cursor down a line. If you are trying to select entire lines, you would be better off using visual line mode, which is activated from normal mode by pressing V (shift-v). This will select the current line in its entirety. You can then extend your selection to include the lines above and below using the k (or up arrow) and j (or down arrow) keys.
When using Vim, I think it is better to go with the grain rather than to fight against it. Don't expect it to work the same way as other text editors. Accept that the Vim way is different.