Emacs semantic+auto-complete-mode for C - 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.

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.

Is there a way to get help for some C functions inside of vim/Neovim?

This question may be a little off topic. But I was wondering if there was a way for me to look at the descriptions of C functions using vim or neovim. Is it possible to look at their documentations by doing something like :help? This would really be helpful since I wouldn't need to lookup to my browser everytime.
I am unclear about these things:
Can :help be my friend here ?
Can I use LSPs to do something like this ?
I am using latest Neovim inside Ubunutu 20.04 in WSL. Is this helpful somehow ?
By pressing K, the keyword under the cursor is looked up using a configured keyword lookup program, the default being man. This works pretty much out of the box for the C standard library.
For C++, you might want to look at something like cppman.
Well yes, you can get the description of C functions by using a LSP (language server plugin)! Here is an image of me using clangd as my LSP:
You'd "just" need to install the LSP and start it. I don't know how familiar you're with neovim, but just in case if you don't know how to install a plugin or to be more specifique: If you don't know how you can install a LSP server, then you can do the following:
There're plenty videos how to set up a LSP-Server for your language. Here's an example.
If you don't want to set up on your own, you can pick up one of the preconfigured neovim setups (some of my friends are recommending lunarvim)
But yeah, that's it. If you have any further questions feel free to ask them in the comments.
Happy vimming c(^-^)c
Let's explain how "K" command works in more detail.
You can run external commands by prefixing them with :! command. So running man tool is as easy as
:!man <C-R><C-W>
Here <C-R><C-W> is a special key combination used to put word under cursor from text buffer down to command line.
Same for showing Vim's built-in help page
:help <C-R><C-W>
As it feels tedious to type that, Vim also defines K Normal mode command that does pretty much the same thing. Except the tool name is taken from value of an option named "keywordprg".
So doing set keywordprg=man (default for *nix systems) makes K to invoke !man tool; while set keywordprg=:help is for bultin help.
Also, the option :h 'keywordprg' is made global or local-to-buffer, so any Vim buffer is able to overwrite global setting. For example, this is already done by standard runtime for "vim" and "help" buffers, so they call ":help" instead of "man".
The problem with :!man command is that it shows "black console". It'd be nice if we could capture man's output and open it inside Vim just like a builtin help page. Then we could also apply some pretty highlighting, assign key macros and all such. This is a pretty common trick and it is already done by a standard plugin shipped with Vim/Neovim.
A command that the plugin provides is called :Man, so you can open :Man man instead of :!man man, for example. The plugin is preactivated in Neovim; for Vim you still need to source one file manually. So to make use of this plugin you'll need something like this
set keywordprg=:Man
if !has("nvim")
source $VIMRUNTIME/ftplugin/man.vim
endif
The previous answer recommending cppman is the way to go. There is no need to install a bulky language server just for the purpose of having the hover functionality. However, make sure you're caching the man pages via cppman -c. Otherwise, there will be a noticeable delay since cppman is fetching the page from cppreference.com on the fly.
If you like popups for displaying documentation, convert the uncompressed man pages (groff -t -e -mandoc -Tascii <man-page> | col -bx), and set keywordprg to your own wrapper to search for keywords according to your needs.

Correct way to use the iterate package in Common Lisp

On my Windows XP box with sbcl-1.4.14 I've installed the ASDF using
(load "C:\\Program Files\\clisp-2.49\\asdf\\asdf.lisp")
(require :asdf)
(push "C:\\Documents and Settings\\mayhem\\lisp\\iterate\\" asdf:*central-registry*)
On SLIME
(require :iterate)
(iterate (for i from 1 to 5) (collect (* i i)))
gives The variable I is unbound error
If I do (in-package :iterate), the code above works fine but this time familiar functions such as exit and other functions which I've defined in .sbclrc cease to work, they give The function ITERATE::EXIT is undefined type of errors, for example.
If I do (use-package :iterate), then it gives [Condition of type NAME-CONFLICT] error.
So I began to use the package like this:
(iterate:iterate (iterate:for i from 1 to 5) (iterate:collect (* i i)))
But I think you'll agree that it's a bad style.
How to use the iterate correctly?
Note: I've seen the post about the very similar problem but it didn't help. There aren't many posts or articles about this particular problem.
You need to say (use-package :iterate) before you try to refer to unqualified symbols from the iterate package.
What has happened in your case is this.
You've loaded the iterate system into the running Lisp, creating a package called "ITERATE".
In the "CL-USER" package you've typed (iterate ...), and the reader has worked out that it needs to find or create a symbol whose name is "ITERATE" and which is accessible in the "CL-USER" package.
There is no such symbol, so it creates a new one, CL-USER::ITERATE.
This is not ITERATE:ITERATE so you get an error from the evaluator as it's trying to evaluate the arguments to a function (which doesn't exist, but it doesn't know that yet). In fact the error you're getting is while it's evaluating the first argument in the (for i ...) subform.
Now you say (use-package :iterate) to tell the system to add the "ITERATE" package to "CL-USER"'s search list.
Now there's a conflict: should iterate refer to the existing CL-USER::ITERATE or the newly-accessible ITERATE::ITERATE? (And there are some other conflicts too, probably).
So the system signals an error, and there should be some useful ways to proceed from that, one of which is probably 'unintern all the conflicting "CL-USER" symbols', but you didn't take that option, I suppose.
So now everything is messed up.
And the answer is: use the packages you want to refer to unqualified symbols from before you try to refer to those symbols unqualified.
(Also: Windows XP? I'm impressed by your retroness.)

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

Vim autocomplete from ctags for system headers only works when popup is triggered manually

On OS X, I generated a set of ctags for the system includes using the following command:
ctags -f c -h ".h" -R --c-kinds=+p --fields=+iaS --extra=+q /usr/include
This was run inside of a ~/.vim/ctags/ directory, where I put all of the ctags I generate for system-wide header files (I also have stuff for ROS and CPP that I load conditionally, but that's neither here nor there).
Anyway. The ctags file is set correctly in my .vimrc, and vim can definitely see the ctags, but for some reason the autocomplete popup will only display results from #included header files if I write out the entire symbol and then start backspacing. As an example, if I #include <string.h> in a project, and then I want to call strlen(), and I start to type str in to the active vim buffer, I will only get results for symbols that are currently in the vim buffer. But, if I type out strlen and then start backspacing one or two characters and hit <C-n>, the popup menu will be populated with matches from any other included header files.
EDIT: Turns out, if I just hit "s" then <C-n>, it works as well. So the problem seems to be that it only works if the popup menu is launched manually. Which makes me think that it's a plugin problem (see below)
Additional information:
completeopt is set to completeopt=menuone,menu,preview,longest
I have OmniCppComplete, which I suppose could be interfering with the behavior. It is currently not being conditionally loaded for C++ files only. If you want me to edit and post my OmniCppComplete settings from my .vimrc, just ask.
I also have AutoComplPop installed, but I haven't done anything to configure it, so it's running with its default settings. Haven't really researched the plugin, so no idea if some of it's behavior could be interfering with the results.
I have AutoTag and TagBar installed, but those should only be fiddling with the current directory's local tagfile.
I'm honestly pretty new to Vim, and I just have no idea where to start debugging this issue, whether it be with a random plugin or with my .vimrc settings.
Vim has many specific completion mechanisms.
<C-n> and <C-p> use many sources defined by the complete option. By default, they will provide completion using the current and all loaded and unloaded buffers, tags and included files. While you can usually get quite useful suggestions with these, it is a bit of a "catch-all" solution: it is not reliable at all if you work on reasonably large projects.
<C-x><C-]> uses only tags so it may be a little more useful to you.
And there are many more, see :h ins-completion.
Omni completion is smarter: it typically runs a custom filetype-specific script that tries hard to provide meaningful completion. It is triggered by <C-x><C-o> and you can read about it in :h ft-c-omni. Omni completion is often a better choice when working with code.
Because you have two overlaping "auto"-completion plugins it's hard to say what completion mechanism is at work. You should disable those plugins and play around with the different completion mechanisms available to you.
I have not mastered this yet, but I do think the following observation may be of help.
Vim's default auto complete which can be quite noisy, often gets in the way of what you call with <C-x><C-o>. Specifically, I found myself calling up my tags based completions with <C-x><C-o> only to have them replaced with continued typing with Vim's default suggestions using my open buffers.
The suggestion of shutting off one of the plugins makes sense. In my case the key was how to shut down Vim's default behavior. I have seen several people (and to which I now include myself), set the length of the expression to a high number before triggering Vim's default. For me that is:
let g:deoplete#auto_complete_start_length = 99
... this way you eliminate the default layer of completions that comes and goes regardless of the commands you intended to inform your work.
This still feels like a hack but it helps keep my work focused on the tag-based completions.
FYI: I use NVIM on a Mac.

Resources