VIM Doxygen support - auto asterisk (*) insertion on newline - c++

When I write Doxygen comments (in C file) I would like an asterisk to be automatically inserted on new line (either with the o command or just ↩ ).
Like this example :
/**
* My Doxygen comment being written
And when I hit ↩
/**
* My Doxygen comment bein written
*
^
cursor is here
I have DoxygenToolkit.vim and set syntax=c.doxygen but none does what I want.
I also found that but not sure what it is supposed to do, but doesn't solve my problem.
I've googled for it but did not find.
Any idea?

You need this in your ~/.vimrc:
filetype plugin indent on
I don't know about DoxygenToolkit.vim, I have never used it. The above is all it takes to enable the described behaviour in my 7.x Vims.
You can find my commented ~/.vimrc online. Nothing too fancy in there, just what I use every day on half a dozen different Linux / AIX boxes. Perhaps there is more in there that you would like.

:setlocal formatoptions+=ro
does that (:help fo-table).
o Automatically insert the current comment leader after hitting 'o' or
'O' in Normal mode.
r Automatically insert the current comment leader after hitting
<Enter> in Insert mode.
Put this into ~/.vim/after/ftplugin/c.vim. (This requires that you have :filetype plugin on; use of the after directory allows you to override any default filetype settings done by $VIMRUNTIME/ftplugin/c.vim.) Alternatively, you could define an :autocmd FileType c ... directly in your ~/.vimrc, but this tends to become unwieldy once you have many customizations.

Related

How to set up clang-format comment pragmas so multiline doxygen comments don't get touched?

I am trying to introduce clang-format to a couple of our projects at work (C and C++), but I am having trouble getting it to format multi-line Doxygen comments the way I want.
All comments have the same format:
/*! #brief Some text
*
* Some more text
*
* #verbatim
*
* A very long line of text that exceeds the clang-format column width but should not be touched
*
* #endverbatim
*/
I want clang-format to leave the verbatim blocks alone and not reflow them. I am using clang-format-6.0
Turning ReflowComments off is not an option as non-doxygen comments must be taken care of by clang-format
I have tried various regular expressions in the CommentPragmas config item but to no avail:
#verbatim(.*\n)*.*#endverbatim to treat the entire verbatim block as a comment pragma. This is the ideal situation, as any other part of the Doxygen comment I do not mind being broken into multiple lines.
#brief(.*\n)+ to match the entire comment block as the pragma. I've also tried this with an arbitrary token at the end of the comment to act as an explicit end-of-block marker. This isn't ideal as it doesn't force the non-verbatim part of the comment to conform, but is a compromise I'm willing to live with if I have to.
Various other regexes I've seen in other discussions, adapted to fit our Doxygen markup.
All I've managed to get it to do so far is to leave the first line of the multi-line comment alone, if it happens to exceed the column limit. However, any following long line is still broken up.
The only other tool I have left in my box is to use // clang-format off and // clang-format on around these comments but again I'd like to avoid it if I can because:
a) it'll be quite tedious to add them throughout the code base
b) I'll have to surround the entire comments with these, rather than just the verbatim blocks (I haven't figured out if you can disable it just for a portion of a multi-line comment - I've only managed to get it working for an entire one, and even if that was possible the clang-format directives would end up in the generated Doxygen docs which is unacceptable)
c) I don't really like the way it looks in code.
Any help is appreciated. Thanks.
Ran into this issue also, and the only work around found was to use clang-format on/off.
clang-format re flowing comments tends to:
break #page, #section, etc titles, and links generated from them (in rare cases).
break #startuml blocks, which have a specific syntax.
break #verbatim blocks.
See an example of usage in MySQL:
https://github.com/mysql/mysql-server/blob/8.0/storage/perfschema/pfs.cc
Update:
Filed a feature request on clang-format itself:
https://bugs.llvm.org/show_bug.cgi?id=44486

Remove pressed key from vim input buffer

I'm writing a vim auto-command for cpp files where I want an abbreviation for #include lines.
The goal is for the abbreviation to expand to #include <▐> with the pipe being the location of the cursor after expansion.
Since naturally the abbreviation is to be followed by a space I'm trying to remove the input space from the register and move on.
However even after exiting insert mode and returning, or any trick I could think of: deleting next key, keying in bs etc, the space is being entered after whatever series of commands the iabbrev includes.
Therefore I'm looking for something that will remove the space from the register AND put me still in insert mode.
Thanks.
Add this to your .vimrc:
autocmd FileType cpp iab <buffer> #i #include <><Left><C-R>=Eatchar('\s')<CR>
func Eatchar(pat)
let c = nr2char(getchar(0))
return (c =~ a:pat) ? '' : c
endfunc
In lh-cpp, I have in a C ftplugin (the place where such definitions should be)
iab <buffer> #n <C-R>=lh#map#no_context("#n ",'\<esc\>0i#include')<CR>
:Brackets < > -open=function('lh#cpp#brackets#lt') -visual=0
With lh#map#no_context() that prevents the expansion of #n within string and comment contexts -- sometimes, we want to be able to type auto s = "#n";, and lh#cpp#brackets#lt that recognizes a few contexts in which I can expand my < into <> (includes, templates, castings, etc).
As you see I don't automatically append "" nor <> here as I want to be able to choose between #include <foo> and #include "foo"
Back to abbreviations that don't eat the space characters, the answer is in the help, see Menix's answer.
To simplify my task, I've defined a command that automatically applies such function (in lh-brackets this time):
command! -narg=+ Iabbr execute "iabbr " <q-args>."<C-R>=lh#map#eat_char('\\s')<CR>"
command! -narg=+ Inoreabbr
\ execute "inoreabbr " <q-args>."<C-R>=lh#map#eat_char('\\s')<CR>"
Thus, I would define your abbreviation this way
:Inoreabbr <silent> <buffer> #n< #include <><left>
:Inoreabbr <silent> <buffer> #n" #include ""<left>
Or even better to not see these abbreviations triggerred in string and comment contexts:
:Inoreab <buffer> <silent> #n< <C-R>=lh#map#no_context("#n< ",'\<esc\>0i#include <>\<left\>')<CR>
" and so on
As you can see from #LucHermitte's answer (and the similar attempt by #Meninx before), eating that character is a bit involved.
Instead, I would recommend you upgrade to a snippets plugin (if you don't use one already). Snippets are like the built-in :abbreviate on steroids, usually with parameter insertions, mirroring, and multiple stops inside them. One of the first, very famous (and still widely used) Vim plugins is snipMate (inspired by the TextMate editor); unfortunately, it's not maintained any more; though there is a fork. A modern alternative (that requires Python though) is UltiSnips. There are more, see this list on the Vim Tips Wiki.
Depending on the snippet plugin, the expansion may need to be explicitly triggered, others may already support insertion without the trailing space. Usually, you can configure a default for the included filename (that can be overwritten easily) - this functionality cannot be had via Vim abbreviations alone.
alternative
If you don't want full snippets functionality just for this, I would recommend to define the abbreviation based on triggering it with <Enter> instead of <Space>. This should fit well for this example (the next code / #include will be on a new line, anyway), and so you don't have to artificially remove anything.

Is there any multiline commenting support for C/C++ languages in Atom Editor?

I'd like to enable multi line commenting support in my Atom editor. I'd like the editor to automatically add a * and a proper indentation at the beginning of new lines of a multiline comment. Here's a sample of what I'm looking for:
/***
* This is a comment
* when I'm adding a new line it automatically adds " * ".
*/
I've tried to look for such package in the Atom package search, on the SO and google but I failed to find anything. I must have typed wrong key words.
I know that geany editor has such a feature so I guess that Atom has one as well.
So, I didn't know that the keyswords should be block comment.
I managed to find an excellent extension which is described as a helper package for writting documentation.
One way or another it does what I was looking for. Here is a link to the repo: https://github.com/nikhilkalige/docblockr

Easily comment (C++) code in vim

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.

Vim different textwidth for multiline C comments?

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.