How to keep my own CR in Vim with automatic format? - vim

I used set fo+=a in Vim to enable automatic format when typing.
With that set, the <CR> I pressed will be erased when I continue to type, if the length of current line is less than lw, and that is not what I want.
What I want is:
Still able to add a <CR> automatically if the line is longer than lw.
When I type a <CR> manually when the line length is less than lw, I don't want that <CR> erased when I continue to type.
Thanks.

You can't. The format option "a" is designed to reformat your paragraph every time your paragraph is changed, so there's no way for you to keep any single line breaks inside your paragraph, regarding the definition of "paragraph" in VIM.
If you only need to be able to wrap long lines while typing, you don't need option "a". Option "t" is already quite sufficient for your case.
t Auto-wrap text using textwidth

If you are fine with using trailing spaces to indicate that a paragraph continues (by default it only ends on an empty line) then you can also do
set fo+=w
. Then to keep vim from joining lines all you need is to end it with something other then a space.
Note: this is not going to change the meaning of the paragraph for motion commands (in fact, there is nothing that can do change it).

Related

Limit the number of characters per line editor vi linux

I am trying that in the editor vi, limit the number of characters per line you can do. Once you reach those x characters, break the line with a carriage return. For example: limit 50 characters.
I have not seen that there is any command (like :set nu to write the numbers of the lines in editor vi) or something similar to activate it.
I know that in order for it to take effect I have to create the file ~/.vimrc but there I don't know how to edit it so that when I later create a file, I restrict it.
Are you really using vi? You are probably using vim. If so, :help will answer most of your _I don't know_s. From there, you can also jump to specific parts of the help following the links (you recognize them as they are likely colored, bolded, or highligthed somehow) by hitting Ctrl+] (and yes, you can also enter :help ctrl-] to see the help on the key combination I've just mentioned).
In order to do what you want, it is enough that you put set textwidth=50 or set tw=50 in your ~/.vimrc file (note that a value of zero for tw means that the option is disabled, or if you prefer, that tw is infinite). If you want to look at the description of this option, enter :help textwidth.
This setting (:set tw=50), however, won't change already existing lines; in order to change all the already existing lines according to the current setting of tw, you can do gggqG, which moves to the first line (gg) and then formats the lines (gq, for info enter :help gq, which will also reveal the reason why this command will have an effect even if tw is 0) till to the last line (G moves to last line of file).

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.

VIM - How can I put my current position in jumplist?

I am wondering about a improvement for vim that I can jump back for where I was the last time I stopped to move around for like 3 seconds. Then I can scroll around and have a kick shortcut to jump back where I was with the same old CTRL+o.
Vim put a lot of movements in the :jumps list and I wondering that half of that is useless in any moment for me, so how could I do that ?
In any another words I'm trying to make the jumplist more sensible.
ps: Netbeans and VS has a similar behavior.
To have the current position automatically added to the jump list, you can utilize the CursorHold event:
:autocmd CursorHold * normal! m'
Navigation is with the default <C-o> / <C-i>.
It's common to use the m and ' commands to jump around. For instance, you can type mx, go off and do some things, and then do 'x to jump back to where you were when you did mx. This works for every letter of the alphabet (i.e. ma, mb,... mz). Uppercase marks (mA, mB,...) will also remember the filename so you can jump between files. There are a number of other special marks you can set for various purposes.
The "previous context mark" is called '. It is set automatically when you jump around, and can also be manually set with m'. Jump to it with ''. The m' command also manually adds a jump to the jumplist. '' is roughly equivalent to Ctrl+O, but doesn't take a count.
If you replace the apostrophes in these commands with backticks, Vim will jump to the specific column rather than just the line. In practice, apostrophe is easier to type and often close enough.
You can set a mark in the ' register. The keystrokes would be m'
I found this in vim's documentation :help jumplist.
You can explicitly add a jump by setting the ' mark with "m'".

Fixing too long comment lines in Vim

I'm looking for a convenient way to fix comments where line lengths exceed a certain number of characters in Vim. I'm fine with doing this manually with code, especially since it's not that frequent, plus refactoring long lines is often language, or even code-style dependent, but with comments this is pure drudgery.
What happens is I often spot some issue in a comment, tweak one or two words and the line spills out of the, say, 80 character limit. I move the last word to the next line and then the next line spills, and so on. Does anyone know a way to do this automatically in Vim?
I would recommend putting the following into your vimrc if this is a regular issue:
nnoremap <leader>f gqip
This maps the leader f shortcut (f is for "format") to format the comment (considered a paragraph after setting some formatoption flags) with gq which formats the comment to be the width of the currently set textwidth or tw option. You should set textwidth in your .vimrc with textwidth=80.
Formatoptions is the other thing you should fiddle with, specifically in your case by adding the acq flags with formatoptions+=acq. Be careful to remove the t flag with formatoptions-=t because that will automatically wrap all of your code, not just recognized comments. After doing all this you should be able to hit f and format inside only the comment, irrespective of whether is is surrounded by blank lines.
Here is the relevant info on formatoptions so you can make your own choices.
t Auto-wrap text using textwidth
c Auto-wrap comments using textwidth, inserting the current comment
leader automatically.
r Automatically insert the current comment leader after hitting
<Enter> in Insert mode.
o Automatically insert the current comment leader after hitting 'o' or
'O' in Normal mode.
q Allow formatting of comments with "gq".
Note that formatting will not change blank lines or lines containing
only the comment leader. A new paragraph starts after such a line,
or when the comment leader changes.
w Trailing white space indicates a paragraph continues in the next line.
A line that ends in a non-white character ends a paragraph.
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.

Wrap long lines in Vim?

I've noticed that gq does not work when I paste in a long line. For example, with a textwidth=72 and formatoptions=tcroqbnl, gq refuses to wrap this (in insert mode, I pasted the entire label contents, and then exited insert mode with ESC):
<label for="contact_reason_1">To get assistance with or to confirm a tire replacement recommendation</label>
If I add a line break in (after "to", for example), it'll wrap then. The funny thing is if I join the line back together, it'll happily wrap it again. So VIM seems to somehow be remembering "oh, this is one paste, don't wrap it".
How do I turn that feature off? I'd like gq in command mode to always work. Taking l out of formatoptions did not seem to help (and it shouldn't, this isn't insert mode).
clarification
Yes, I'm using a motion command, in particular, gq<Right>. formatexpr and formatprog are both unset. If it matters, this is in gvim on Debian GNU/Linux, vim version 7.2p284.
steps to reproduce
Pop up gvim on an open file.
Press i to get into insert mode, then type This is a long line. A long line. But not wrappable yet. Or yet. Soon.
Press ESC, then I. Type Now putting text in front of the long line. note: there is a space after the final period, can't get SO to show it, except when this note is here. FUN.
Press ESC, then A. Type And some after. note: space before the And, same SO problem.
Press ESC one last time. Now try gq<Left>, note it only wraps And some after.; I can't get vim to wrap the rest of the line (without going into insert mode and doing a line break by hand, then it works).
Fixing this state is doable; putting a newline after "now" and then hitting undo makes line wrap work again. WTF.
gq isn't enough to wrap the text. You have to give it a motion over which to wrap (like gqj) or tell it to wrap the current line with gqq. Are you sure you're not just mistyping it?
If you aren't, what are the formatexpr and formatprg options set to, if anything?
Update
The problem is the b setting in formatoptions. That's telling Vim to only wrap the text added during the last insertion.
I find that if I select the line before doing the gq, it works fine. Doesn't gq want to be combined with some text selection operation to work?
UPDATE
I confirm the bug. Running vim -u NONE, my formatoptions are vt.
Maybe Bram Molenar or at least the vim community would be interested?

Resources