Emacs comment-region in C mode - c

In GNU Emacs, is there a good way to change the comment-region command in C mode from
/* This is a comment which extends */
/* over more than one line in C. */
to
/* This is a comment which extends
over more than one line in C. */
? I have tried
(setq comment-multi-line t)
but this does not help. There is a section on multi-line comments in the Emacs manual, but it does not mention anything.

Since Emacs 21, there's been a module named 'newcomment, which has different comment styles (see the variable 'comment-styles. This setting gets close to what you want:
(setq comment-style 'multi-line)
(Note: you should probably make that setting in 'c-mode-hook).
However, none of the settings make the comments look like what you want.
The easiest way I saw to get what you want is to add this hack:
(defadvice comment-region-internal (before comment-region-internal-hack-ccs activate)
"override 4th argument to be just spaces"
(when (eq major-mode 'c-mode) ; some condition here
(let ((arg (ad-get-arg 4)))
(when arg
(ad-set-arg 4 (make-string (length arg) ?\ ))))))
The current settings for comment-style always prefix the comment lines with " * " (if not the whole " /* ").
If you don't have Emacs 21, I suppose you could simply download newcomment.el from the repository. I don't know if it works as-is in earlier versions of Emacs, but it might be worth a shot, though upgrading Emacs would be a better solution.
My hack breaks the 'uncomment-region. A proper fix would be to change 'comment-padright. That would take a little more research so as not to break other things. The above hack only changes behavior in 'c-mode (adjust the condition to your liking).

Closest I could find with the built-in commenting support is if you set comment-style to multi-line, which will produce this:
/* This is a comment which extends
* over more than one line in C. */
If that isn't close enough, take a look at newcomment.el and define your own commenting functions as appropriate.

Related

.emacs: c-set-style will delay display of new style until I change the buffer (type a key)

Dealing with files of different C flavours, I defined the following function and a keyboard mapping to invoke it:
(defun my-c-set-gnu-style ()
"doc string"
(interactive)
(setq tab-width 8
indent-tabs-mode t)
(c-set-style "gnu")
)
(global-set-key (kbd "C-x :") 'my-c-set-gnu-style)
Now when I open a C file with emacs, and then type C-x: then nothing happens. Only after I hit some key (and thus I change the code, which is really bad), emacs will re-draw the code according to the new style.
How can I achieve that emacs will re-indent the code right after the respective command has been issued? The need to change the file is really bad.
Version is GNU Emacs 26.3.
The issue isn't related to c-set-style. Changing the TABs mode like in (setq tab-width 8 indent-tabs-mode t) should also have an immediate visual effect — which it does not have.
Using (redisplay t) didn't solve the problem, but what worked is (force-window-update) at the end of the defun. Dunno if that's supposed to be issued by hand or whether the requirement is an Emacs bug, though.

How to use Doxygen with Prolog

I was struggling trying to make doxygen work with prolog.
At first I was only trying to include an "external and unknown" file, but as doxygen users know, it won't print a thing if it can't find useful (documented) functions.
Searching stackoverflow for both tags gives no single answer, and so I decided to ask, even if I already solved the puzzle, so people will have a hit in case of search.
I will let this question here, as people can suggest simple workarounds, and we may learn a bit more about the subject, but I'll use it to register my own answer after some (hard) efforts. Thanks.
To explain where I did start:
My first (almost) successful approach worked fine in a program that used both C and PROLOG.
It almost worked because latter on I saw this approach would not work in a PROLOG only project.
Anyway, what I did was simply add this
INPUT = README.md groups.dox c-and-pl.c c-and-pl.pl
FILE_PATTERNS = *.pl
EXTENSION_MAPPING += pl=c
EXTRACT_ALL = YES
EXTRACT_STATIC = YES
SOURCE_BROWSER = YES
And PROLOG code would look like:
/**
* #file cpl.pl
* #ingroup GroupUnique
* #brief CPL - C calls Prolog (Prolog module)
* #cond SKIPPROLOG
*/
/* brief explanation in a normal (non-doxygen) comment */
clause(A) :-
rule(X),
test(A, X).
and(so, on).
/** #endcond */
This would work because C would create the site anyway, and PROLOG page would be just a brief, no clauses, but a link to see the complete code, with normal comments explaining the clauses.
Why this doesn't work for a pure PROLOG project? And how to do that?
My second attempt to solve it involved the creation of a new file, a copy of the original PROLOG source, but with comments in doxygen format, and converting PROLOG clauses in something C-like.
Call the source source.pl and the second copy source.dox. You would write the PROLOG program as you usually do, using doxygen before the first occurrence of each clause, atom, module, etc.
Then cp source.pl source.dox and edit source.dox converting all clauses in something like:
/**
* \file source.pl
* \ingroup GroupUnique
*/
/**
* \ingroup GroupUnique
* \brief Defining factorial module
*/
module(fatorial, [fatpl/2]);
This takes time and are prone to errors, but it was a workaround. Problem is that doxygen now lists source.pl twice. But the functions can be documented. Use this configuration:
INPUT = README.md groups.dox source.pl source.dox
You need to keep source.pl because it is there the real source to be seen. And source.dox would be more like a C header file.
Not good. The work to transform manually a source.pl into a source.dox led me to write my own compiler (well, technically a filter, that uses only lexical tokens).
The program is available open source at github:
https://github.com/drbeco/doxygenprolog
and is cited here in the official pages among other filters: doxygen helpers
And a little note here, in the official SWI-Prolog site:
SWI-Prolog news
To make doxygen work with an unknown language you need:
Install this filter in someplace PATH can find.
Edit your doxygen .cfg to have:
OPTIMIZE_OUTPUT_FOR_C = NO
INPUT = README.md groups.dox source.pl
EXTRACT_ALL = YES
EXTRACT_STATIC = YES
FILE_PATTERNS = *.pl *.prolog *.swipl
FILTER_PATTERNS = *.pl="dox4pl"
Now you can run your doxygen as you normally do with other languages.

When cedet semantic parsing c header files of my system, here comes "Idle Parse Error":

No method definition: semanticdb-add-reference, (nil (\"stdio.h\"
include (:system-flag t) (unlink-copy-hook
(semantic--tag-unlink-copy-secondary-overlays) link-hook
(semantic--tag-link-secondary-overlays) secondary-overlays (# #) unlink-hook
(semantic--tag-unlink-secondary-overlays) dependency-file
\"d:/MinGW/include/stdio.h\") #))"
I use mingw in windows 7 system, c.c is the file name, and there are two sentence in init.el which are relevant to the problem:
(semantic-add-system-include "D:/MinGW/include" 'c-mode)
(setq semantic-c-dependency-system-include-path "D:/MinGW/include")
The include path you are setting should be a list, such as:
(setq semantic-c-dependency-system-include-path '("d:/MinGW/include"))
but you don't need that line if you are using semantic-add-system-include.
While I haven't tried it, you can probably skip doing either of the above by instead using semantic-gcc-setup and ask your minGW compiler. Just make sure a command "gcc" is on your exec-path when you start Emacs, and it will be automatically detected.
No one has reported this working or not working for MinGW, so if it works out, let us know.
"M-x customize" then
search "Global Semanticdb Minor Mode" then
toggle on it

Emacs semantic+auto-complete-mode for C

I've been working on making auto-complete-mode work with Semantic nicely but know I'm completely stuck. I've succesfully had semantic autocomplete through semantic-ia-complete-symbol (though for some reason it can't complete malloc(), which is weird).
Some .emacs snippets:
(add-to-list 'ac-dictionary-directories "~/emacs-src/auto-complete-1.3.1/")
(ac-config-default)
(ac-set-trigger-key "TAB")
(add-to-list 'ac-sources 'ac-source-semantic)
(add-to-list 'ac-sources 'ac-source-gtags)
(add-hook 'c-mode-hook
(defun my-c-mode-hook ()
(auto-complete-mode)
(setq ac-sources '(ac-source-semantic))
(ac-complete-semantic)))
How do I make auto-complete-mode work together with Semantic?
If I understand you correctly, Semantic is working and you're only struggling with setting up auto-complete. For doing the latter, simply start with
(require 'auto-complete-config)
(setq-default ac-sources '(ac-source-semantic-raw))
Note that you have to use "setq-default" for setting ac-sources. You should then be able to do
M-x auto-complete-mode
in a C/C++ buffer and auto-complete should query Semantic for completions.
Try debugging the auto-completion failure by:
M-x semantic-analyze-debug-assist RET
and see what it says. Look at \include\stdlib.h to see what the parser thinks of the file. If while there you do:
M-x bovinate RET
then you can search to see if malloc is there. If not, there is probably a parsing bug, or some miscellaneous #define that isn't set up correctly. Using the above you can usually find at a header file to see where things start to break down.

How can I autoformat/indent C code in vim?

When I copy code from another file, the formatting is messed up, like this:
fun()
{
for(...)
{
for(...)
{
if(...)
{
}
}
}
}
How can I autoformat this code in vim?
Try the following keystrokes:
gg=G
Explanation: gg goes to the top of the file, = is a command to fix the indentation and G tells it to perform the operation to the end of the file.
I like to use the program Artistic Style. According to their website:
Artistic Style is a source code indenter, formatter, and beautifier for the C, C++, C# and Java programming languages.
It runs in Window, Linux and Mac. It will do things like indenting, replacing tabs with spaces or vice-versa, putting spaces around operations however you like (converting if(x<2) to if ( x<2 ) if that's how you like it), putting braces on the same line as function definitions, or moving them to the line below, etc. All the options are controlled by command line parameters.
In order to use it in vim, just set the formatprg option to it, and then use the gq command. So, for example, I have in my .vimrc:
autocmd BufNewFile,BufRead *.cpp set formatprg=astyle\ -T4pb
so that whenever I open a .cpp file, formatprg is set with the options I like. Then, I can type gg to go to the top of the file, and gqG to format the entire file according to my standards. If I only need to reformat a single function, I can go to the top of the function, then type gq][ and it will reformat just that function.
The options I have for astyle, -T4pb, are just my preferences. You can look through their docs, and change the options to have it format the code however you like.
Here's a demo. Before astyle:
int main(){if(x<2){x=3;}}
float test()
{
if(x<2)
x=3;
}
After astyle (gggqG):
int main()
{
if (x < 2)
{
x = 3;
}
}
float test()
{
if (x < 2)
x = 3;
}
The builtin command for properly indenting the code has already been mentioned (gg=G). If you want to beautify the code, you'll need to use an external application like indent. Since % denotes the current file in ex mode, you can use it like this:
:!indent %
I find that clang-format works well.
There are some example keybindings in the clang documentation
I prefer to use the equalprg binding in vim. This allows you to invoke clang-format with G=gg or other = indent options.
Just put the following in your .vimrc file:
autocmd FileType c,cpp setlocal equalprg=clang-format
The plugin vim-autoformat lets you format your buffer (or buffer selections) with a single command: https://github.com/vim-autoformat/vim-autoformat. It uses external format programs for that, with a fallback to vim's indentation functionality.
I like indent as mentioned above, but most often I want to format only a small section of the file that I'm working on. Since indent can take code from stdin, its really simple:
Select the block of code you want to format with V or the like.
Format by typing :!indent.
astyle takes stdin too, so you can use the same trick there.
I wanted to add, that in order to prevent it from being messed up in the first place you can type :set paste before pasting. After pasting, you can type :set nopaste for things like js-beautify and indenting to work again.
Maybe you can try the followings
$indent -kr -i8 *.c
Hope it's useful for you!
Their is a tool called indent. You can download it with apt-get install indent, then run indent my_program.c.
For a good overview and demo of many of the options mentioned here, #Gavin-Freeborn has a great video on YouTube:
https://www.youtube.com/watch?v=tM_uIwSucPU
It covers some Vim plugins as well as built-in capabilities such as =, gq, and formatprg.

Resources