To reproduce my issue:
$ vim -u NONE test.cpp
:set nocompatible
:set tw=20
:set fo=croql
Now type in the following text:
/*
test test test test test test test test test
*/
Notice that there is no leading asterisk on the line containing the tests. Vim will insert this by default, remove it.
Vim should be auto-wrapping this, but it doesn't.
How can I make Vim wrap automatically in comments, and only in comments? :set fo+=t works, but then everything gets wrapped and I do not want automatic hard wrapping for code.
With my OnSyntaxChange plugin, you can change the 'fo' option value depending on whether the cursor inside a comment or not:
call OnSyntaxChange#Install('Comment', '^Comment$', 0, 'a')
autocmd User SyntaxCommentEnterA setlocal fo+=t
autocmd User SyntaxCommentLeaveA setlocal fo-=t
It's also available on GitHub.
Sorry, but Vim by itself cannot be configured to automatically wrap text in multi-line comments, without some character at the beginning of the line. The 'comments' option controls how Vim recognizes comments for automatic wrapping. Multi-line comments must have a "s", "e", and "m" part in the 'comments' option to be recognized; :help format-comments says: "Three-piece comments must have a middle string because otherwise Vim can't recognize the middle lines."
Nevertheless, you can still manually reformat such lines with the gq operator (shorthand gqq for a single line) and Vim should mostly do what you want. If it is slightly off, you can mess with the 'formatexpr' option.
You're probably better off just using the leading * in multi-line comments, or using //-style comments.
There are plugins available that use syntax-defined regions in clever ways which may allow you to work around these limitations. See Ingo's answer.
I'm using VIM 8.2 and it CAN wrap comments out of the box.
Short answer how
set tw=80
set fo=croaq
Check your comments option with :set comments?. I must contains /*, * and */ sequences.
Long answer
You can read details in :help formatoptions, :help fo-table and :help comments.
The tw=80 option is for limiting line width.
The formatoptions uses next flags here:
The c flag is to apply wrapping only for comments
The r and o flag is for auto-inserting the comment-leader on new lines (* symbol for /* styled comment in C-like languages).
The a will auto-format your paragraphs while you are typing.
The q option will handle the comment leader the correct way.
For some types of buffers you can apply formatoptions for all text like next:
"Limit line width for git commit messages to 72 characters
autocmd FileType gitcommit setlocal tw=72
"Auto format all text for git commit messages and markdown files
autocmd FileType gitcommit,markdown setlocal formatoptions+=t
Here
The t flag is to apply wrapping for text (additionally to c)
The comments option will help vim to detect comments correctly.
Related
I want to highlight lines that are longer than the set textwidth so that it is dynamic for different filetypes. I have the following:
autocmd BufEnter * highlight OverLength ctermbg=darkgrey guibg=#592929
autocmd FileType * execute 'match OverLength /%\{'.&textwidth.',}v.*/'
This code doesn't seem to activate the highlighting, however, the following does work:
autocmd BufEnter * highlight OverLength ctermbg=darkgrey guibg=#592929
autocmd BufEnter * match OverLength /\%>90v.\+*/
I have tried excluding the execute statement and adding the backslashes accordingly but I still cannot seem to get this to work. Also, I think using the execute statement makes this code cleaner. I would appreciate it if someone could explain to me what I am doing incorrectly.
I have referenced the following examples in pursuit of the answer:
highlight long lines
expand a variable in regular expression
If there is a more portable and cleaner way to go about this then please let me know. I am trying to learn as much as possible.
ANSWER:
What I ended up doing is utilizing vim's vim/after/ftplugin folder hierarchy and adding:
set textwidth=100
let &colorcolumn=join(range(&textwidth+1,999),",")
to each filetype.vim file e.g. markdown.vim, java.vim, vim.vim
And for help.vim and man.vim files I didn't want colorcolumn highlighting so I changed the textwidth in those files to 999. By doing this vim was able to distinguish between different file types when they were open in the same session.
What I ended up doing is utilizing vim's vim/after/ftplugin folder hierarchy and adding:
set textwidth=100
let &colorcolumn=join(range(&textwidth+1,999),",")
to each filetype.vim file e.g. markdown.vim, java.vim, vim.vim
And for help.vim and man.vim files I didn't want colorcolumn highlighting so I changed the textwidth in those files to 999. By doing this vim was able to distinguish between different file types when they were open in the same session.
– user2904000
We're looking at adding Doxygen documentation to C++ header files, but some people would prefer not to see the verbose Doxygen documentation by default.
Is there a way in .vimrc to fold (collapse) Doxygen comments by default?
Note: I have tried autocmd FileType c,cpp set foldmethod=syntax which will collapse all matching syntax, but I have been unable to figure out how to avoid collapsing functions, classes, et al., i.e. to only collapse Doxygen documentation format.
Another solution that looks like it might be a good one if the C-fold plugin for vim. Here's a detailed install sequence to get it working:
Add Doxygen syntax highlighting
(a) Install it from http://vim.sourceforge.net/scripts/script.php?script_id=5 which will create ~/.vim/syntax/doxygen.vim.
(b) Add ~/.vim\ftdetect\doxygen.vim with this single line:
au BufNewFile,BufRead *.doxygen setfiletype doxygen
(c) Add ~/.vim/syntax/doxygen_load.vim with these two lines:
au! Syntax {cpp,c,idl}
au Syntax {cpp,c,idl} runtime syntax/doxygen.vim
Add at the end of ~/.vimrc:
let mysyntaxfile='/home/dchinner/.vim/syntax/doxygen_load.vim'
autocmd FileType c,cpp set foldmethod=syntax
autocmd FileType c,cpp set foldlevel=10
Note that foldlevel determines how much will be folded initially. A high value will ensure most is open.
Add C-fold to (un)fold code or comments
(a) Install it from http://vim.sourceforge.net/scripts/script.php?script_id=1145 which will install ~/.vim/plugins/cfold.vim and ~/.vim/after/syntax/c.vim.
(b) Add at the end of ~/.vim/syntax/doxygen.vim:
syn region doxygenComment start= ... keepend fold
Done! You can now use these C-fold plugin key-combos:
z[ opens all doxygen-style comments
z] closes all doxygen-style comments
z{ opens all code blocks
z} closes all code blocks
vim a file with Doxygen comments, and hit z] to fold the Doxygen comments.
Both syntax/c.vim and syntax/doxygen.vim use syntax folding. Since there is no condition around the fold definitions in c.vim, you cannot turn off just one part.
You have to fork the default $VIMRUNTIME/syntax/c.vim into ~/.vim/syntax/c.vim, and remove all fold attributes from the syntax commands. That should leave just the doxygen parts folded (with :set foldmethod=syntax). The downside is that you have to maintain your special version of c.vim from now on.
Inside a function I use to initialise some TeX related settings I have the following mapping defined:
vmap <buffer> ucm :s/^\% //<CR>:nohlsearch<CR>
I expected it to allow me to easily uncomment visually selected lines. The analogous:
vmap <buffer> cm :s/^/\% /<CR>:nohlsearch<CR>
does a pretty nice job in commenting. Also analogous mappings for other languages, which use a #, and not a % work just fine. Those last ones look like this:
vmap <buffer> cm :s/^/# /<CR>:nohlsearch<CR>
vmap <buffer> ucm :s/^# //<CR>:nohlsearch<CR>
A sequence of V10jcmV10kucm is supposed to leave the code intact.
So now: What am I doing wrong?
You are adding unecessary stuff.
:s/^/% <CR>
and
:s/^% /<CR>
should work for commenting and uncommenting respectively.
The third / is used to add options such as /c for "confirm" or /g for "global". If you don't use those options you don't need this / at all.
In your "uncomment" substitution you are escaping % but % in itself has no special meaning for Vim's regex flavour. Not only Vim is certainly not going to match it if it's escaped but \%<something> is used for a bunch of atoms like \%d. So your pattern fails because Vim stumbles upon your \% expecting the rest of the atom and getting "nothing".
I have looked at the following question:
How to comment out a block of Python code in Vim
But that does not seem to work for me. How do I comment code easily without resorting to plugins/scripts?
Use ctrl-V to do a block selection and then hit I followed by //[ESC].
Alternatively, use shift-V to do a line-based select and then type :s:^://[Enter]. The latter part could easily go into a mapping. eg:
:vmap // :s:^://<CR>
Then you just shift-V, select the range, and type // (or whatever you bind it to).
You can add this to your .vimrc file
map <C-c> :s/^/\/\//<Enter>
Then when you need to comment a section just select all lines (Shift-V + movement) and then press CtrlC.
To un-comment you can define in a similar way
map <C-u> :s/^\/\///<Enter>
that removes a // at begin of line from the selected range when pressing CtrlU.
You can use the NERD commenter plugin for vim, which has support for a whole bunch of languages (I'm sure C++ is one of them). With this installed, to comment/uncomment any line, use <Leader>ci. To do the same for a block of text, select text by entering the visual mode and use the same command as above.
There are other features in this such as comment n lines by supplying a count before the command, yank before comment with <Leader>cy, comment to end of line with <Leader>c$, and many others, which you can read about in the link. I've found this plugin to be extremely useful and is one of my 'must have' plugins.
There's always #ifdef CHECK_THIS_LATER ... #endif which has the advantage of not causing problems with nested C-style comments (if you use them) and is easy to find and either uncomment or remove completely later.
In our C++ code base we keep 99 column lines but 79-some-odd column multiline comments. Is there a good strategy to do this automagically? I assume the modes are already known because of smart comment line-joining and leading * insertion.
Apparently both code and comments use the same textwidth option. As far as I can see, the only trick is to set this option dynamically:
:autocmd CursorMoved,CursorMovedI * :if match(getline(.), '^\s*\*') == 0 | :setlocal textwidth=79 | :else | :setlocal textwidth=99 | :endif
Here the critical part is detecting when we are in a comment. If you only format comments this way:
/*
* my comment
*/
my regex should work... unless you have lines in the code starting with * (which I guess can happen in C, less frequently in C++). If you use comments like this:
// comment line 1
// comment line 2
the regex is even simpler to write. If you want to cover all possible situations, including corner cases, well... I guess the best thing would be to define a separate detection function and call that from the :autocmd instead of match().
I came across this same problem and think that I have found a suitable solution.
What I wanted my comments to word wrap so that when I'm typing I don't have to worry about formating text. This works well with comment text. But I wasn't comfortable with having vim format my code. So I wanted vim to highlight every thing in red after x column.
To do this with only cpp code you would add the following to your ~/.vim/ftdetect/cpp.vim file.
set textwidth=79
match ErrorMsg '\%>99v.\+'
note: You may have to create the file and folders if they don't exist.
If you have problems with this make sure that you have formatoptions set to:
formatoptions=croql
You can see this by running :set formatoptions inside of vim.