skeeto / w64devkit

Portable C and C++ Development Kit for x64 (and x86) Windows
The Unlicense
3.1k stars 216 forks source link

Include cscope? #149

Open MichaelAgarkov opened 3 months ago

MichaelAgarkov commented 3 months ago

Vim supports cscope out-of-the-box, and can also be used for C++ code.

skeeto commented 3 months ago

When I looked into it years ago, I saw there wasn't a native Windows port and didn't investigate further. However, I just took a closer look, and a port is more feasible than I realized. It requires POSIX regex which I've since solved (#127), and PDCurses is already a dependency for GDB. It also needs fork() and some other unix functions, but the existing DOS (djgpp) port covers nearly all of that, and the DOS port be extended to Windows.

So PCRE2 with contrib/libregex.c, PDCurses, and a patch with a handful of changes to port to Windows ought to do it. That all even builds natively in w64devkit itself, too. I still need to consider whether I'd want to include cscope, but it shouldn't be blocked by a technical problem.

N-R-K commented 3 months ago

The main reason I use cscope over ctags (IIRC) is that it allows listing all the places where a symbol occurs along with all the places where a function is called. It's not perfect, since it seems to (?) operate at a textual level and not at a AST level (i.e macros, pointers etc will fool it) but it's better than nothing compared to ctags which only lets you jump to definition.

And while vim does have builtin support for cscope (note that neovim has removed it) I find the interface quite intrusive. I personally use quickr-cscope plugin which has no-nonsense interface that populates the quickfixlist and lets me work at my own pace without any annoying interactive ui popups.

As for including cscope in w64devkit, it wouldn't make much difference to me personally. I try to do most of the editing in my linux machine while using w64dk mainly as a way to compile/test the result.

skeeto commented 3 months ago

Thanks for the insight, NRK. I was aware of Vim's cscope integration, and this thread prompted me to investigate and try it out. My impressions were similar to yours. When I searched how people actually use it, I learned it requires significant customization to get a smooth, streamlined interface. That is, if they weren't using a third-party plugin altogether like you.

This is like my situation with gofmt / goimports. Despite being a simple filter with quickfix-friendly output, Vim does not integrate it well. The only decent options are heavyweight, third-party plugins. I put a hack in my vimrc, but it still doesn't quite work right. Vim extensibility isn't so great and is missing to many obvious (to me) basic features. All the better that it's so batteries-included, even with poor defaults.

My current solution for "find usage" is a project-wide vimgrep using the last searched symbol (i.e. loaded with *):

map / :execute "vimgrep // */." . expand("%:e")

To avoid irrelevant matches, especially in binary files (Why does vimgrep match binaries, with no disable option?! Again, obvious but missing.), it searches files matching the current file extension, which misses header files — sometimes good, sometimes bad. It works quite well with C, which rarely "overloads" names, and less well with C++ (namespaces, overloads) and OOP generally (e.g. Python) due to non-unique method names.

Honestly, the cscope curses interface is quite terrible. If I included a ported cscope, I'd be tempted to rip it out entirely alongside the Windows patches, leaving only the "line-oriented interface." That's the protocol Vim and such use, after all. I'd be surprised to learn anyone's seriously using the curses interface.

I've been tempted on occasion to write a new ctags / cscope from scratch, giving it the same treatment I did with u-config for pkg-config. Universal Ctags is acceptable, but it's a bit slow and does too much (e.g. indexing non-code stuff like JSON keys, Markdown headings, etc.). No full AST parse (god help me), but rather a C++ tokenizer that heuristically tracks scope, namespaces, and maybe some type information. Doesn't have to be perfect, just good enough. Plus imperfection permits more performance, perhaps even eliminating the database entirely.