Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Using Vim for C++ Development (gist.github.com)
222 points by ingve on Sept 3, 2020 | hide | past | favorite | 156 comments


Before switching to CLion eventually, I've used my well curated VIM config[1] together with YouCompleteMe and several clang-based tools such as clang-format, clang-rename etc. for several years, working on smaller and large C/C++ codebases with reasonable success.

At some point in time I switched to a full-fledged IDE (CLion) because there are certain refactoring tasks which are probably still possible using this setup but I found them to be mentally too complex to deal with, especially when I am focusing on the task at hand at the same time.

[1] https://github.com/NewProggie/Dev-Utils/blob/master/dotfiles...


+1 to CLion. Vim is great for what it is-- if I need to make a small edit or even work on C code it does the job well and is very fast and efficient. But at the end of the day it's not a full blown IDE and as such is missing a graphical debugger and profiler, good configuration for interactively running unit tests, and complex refactoring tools.

CLion is pretty much the best C++ IDE I've found by a mile. Eclipse is so slow and terrible I won't even consider it. Visual Studio is amazing but Windows only and really heavyweight. VSCode, Atom, etc. aren't really "proper" IDEs. Then there's open source contenders like Jucipp which while very fast do lack a lot of the niceties of their paid competitors.

My only gripe with CLion is that it's CMake only. This limits its usefulness for Bazel or Autotools projects.


Clion added support for Makefile based projects back in July. https://www.jetbrains.com/help/clion/makefiles-support.html


What are you missing in VSCode to make it a proper IDE?


VSCode gets the look right. Indeed, its look is fantastic. But it doesn't get the feel of vim right at all. My fingers speak vim and they know whether they're talking to vim or something hinky. So after a few days with VSC, I go back. Usually it has to do with ex mode which I power edit in a lot. But I do look at VSC every year or so and it gets better.


The lack of a built-in profiler was a big one for me (though this may have improved recently). I do like using external tools like Intel VTune or Morgan Stanley's XPedite but they're not great for the "quick profiling" you might do to test out various implementations of a function or component.

Maybe that's been added since I used it 1.5 years or so ago though.


Graphical debuggers, GUI tooling framework for MFC/UWP/WinUI, mixed mode debugging .NET/C++, navigation in binary libraries, architecture diagrams, graphical class navigation.


> Eclipse is so slow and terrible I won't even consider it.

Ironically it was a similar experience with InteliJ that made me love Eclipse again.


> Eclipse is so slow and terrible I won't even consider it

Very funny! On our codebase CLion is very, very, very slow.


That would be my advice, if you are comfortable with vim it will be a great tool for small to mid projects. Maybe even larger ones that are clearly modularized and kept lean.

But you cannot escape the reality, refactoring kinda needs a good IDE to get it done quickly.


An IDE or the equivalent of an IDE implemented as a language server.

Using language servers make me wonder why it took so long to figure this out. Pretty much all IDEs are awful for text editing if you're a Vimmer but superior for the refactorings you're going to need. Programs like Vim are excellent text editors but JetBrains is never going to invest in VimScript.

I am occasionally frustrated that sometimes I am still forced to choose between one or the other because a lot of the servers are still in their infancy. Still waiting for the equivalent of Visual Studio 2019 as a language server that actually works with the projects I have to develop.


Language servers + vim are sometimes not as performant (or efficient) as an IDE.

Once, I tried replacing IntelliJ with vim + deoplete + a linter plugin (whose name I forgot), because Intellij ate my laptop battery too quickly, and because I like editing text in vim more than IntelliJ.

Well, the vim setup ate through it twice as fast, and was slightly less responsive.


In IntelliJ, it is possible to open the current buffer/editor in emacs using emacsclient. You can configure Tools > External Tools in the preferences. With this, you can have the same line number centered in emacs.

There could be something similar for vi too, though I have not explored this route.

Could this be a good compromise?


At least jetbrains has a vim plugin for all it's IDEs, you know?


There are still a lot of little differences which were fundamentally the reason I even switched to Vim in the first place. The tab switching and window splitting alone is something that drives me mad every time I have to use a Jetbrains IDE. Not to mention IDEs always insist on auto-formatting code while I'm typing it, which feels like using a site where the content jumps around because the ads are still loading.


Unless they fixed it in the last year or two, the interactions between JetBrains selection (necessary for a lot of the IDE magic) and Vim visual mode (what you'd actually use in the IdeaVim bindings) weren't always very predictable. That prevented the easymotion clone from working quite like the plugin, other things along those lines.

I found it to be a very good emulation of vanilla Vim, but also found when I was using Vim mode I hardly used any of the IDE features aside from passive JSDoc/outline/etc displays. That lack of integration between the two halves killed it for me, not to mention it'd been a long while since vanilla Vim was what I was really using.

I love the Language Server concept and hope that just becomes the thing going forward. There was never any reason specific language knowledge should be part of the editor, other than we didn't have a vertical enough ecosystem yet to coordinate a different way. Whatever else I can say about Microsoft, they accomplished that vertical pretty skillfully with VSC and TypeScript, and have been running with it like mad. I'm glad some of that has been to our general benefit.


The code is being auto formatted because you are writing it in a way that doesn't align with your formatting rules! :)

I think you can change that to only on file save, though.


You don't have to pick one. I write my projects in vim and keep the IDE open for when I want to refactor/debug. I'm not against using the IDE mind you, I sometimes refactor then keep on typing in the IDE. But I find myself naturally drifting back to vim when I'm just writing code.

(I'm also a firm believer in getting familiar with the default keybindings for any program, so I don't use any vim emulation in an IDE. There's value in learning a set of shortcuts that are usable everywhere)


I agree, there is no silver bullet for anything. Editors, languages, tools, cars etc.

Every tool has trade-offs, knowing how to use each and when to used them is going to help you work faster and smarter.


CLion (and other IDEs) have pretty good vim plugins: IdeaVim, VsVim , Vrapper.

They're not perfect, but I also made the switch from vim to CLion and never looked back. With a half-decent plugin for editing text, there's not much value in using a more minimalist vim setup IMHO.


How does VsCode compare for C++/Cmake development?


Having used vim for several years, switching to VS Code greatly improved my productivity. Having an in-app file tree, and being able to quickly peek at definitions or all references of a variable are convenient features to have, and IMO not matched by any similar vim plugin. I feel the greatest advantages of Vim are its small memory footprint and keybindings, but it is possible to use plugins in VSCode for the latter and the former is something that has not affected me too greatly.


It's decent, though the debugger isn't quite as pleasant to use and it lacked a profiler last time I checked. But the actual editing experience is excellent and it uses libclang for a backend so you get up to date features for the latest C++ incarnations.


Yeah, lets take lightweight vim and add a node.js runtime and make a better ide.... sigh

At that point you might as well use QT Creator.


Some folks really like Vim more than "vim-mode" for any given editor. I don't see any problem here if no one is forcing you to use it. (It's not built in to Vim).

There are a ton of people that use Vim because it's productive, not because of how "lightweight" it is. I see no reason to shame people if they choose to use "heavy" plugins to achieve whatever functionality they want.


>There are a ton of people that use Vim because it's productive, not because of how "lightweight" it is. I see no reason to shame people if they choose to use "heavy" plugins to achieve whatever functionality they want.

because vim wasn't exactly built with these kinds of features in mind and it shows when you start to throw a lot of IDE features into vim. For example switching to very large text files with vanilla vim, doing some search and replace is no problem, it's super fast.

Doing that with the wrong plugin on that does some CPU heavy stuff can very quickly make vim unresponsive.

IDEs are already built with a rich feature set in mind, so you can expect performance to be relatively stable. Vim or Emacs with the entire kitchen sink thrown in tends to be a little bit dicy


Perhaps. But since it's not main-lined into the actual application, it's no big deal. If people want to "pimp" their Vim with airline, and any other odd nonsense, that's fine. If they want to include an entire nodejs process to provide auto-complete, that's fine too. I'm simply saying that the fact that it was originally conceived as a lightweight text editor, doesn't mean that people should be shamed for making it so much more. I personally have found Vim to be my favorite tool, and nearly EVERY attempt at other IDEs to emulate it, I've found lacking. So, I choose to extend Vim.


> because vim wasn't exactly built with these kinds of features in mind and it shows when you start to throw a lot of IDE features into vim.

I disagree. Both Vim and Neovim are under active development, and have acquired many features to support IDE functionality.

> For example switching to very large text files with vanilla vim, doing some search and replace is no problem, it's super fast.

This has improved a lot in the last few years thanks to the async APIs.


The CoC plugin mentioned (which uses node) isn't the only option - LanguageClient-neovim works great and is written in Rust (and works with vim or neovim despite the name), also the upcoming Neovim 5 will have built in support for language servers.

EDIT: Also, the actual language server (clangd, ccls, etc) which is compiling/reindexing your project behind the scenes is generally the most resource intensive part of the whole setup - so even CoC with node is not a bad choice.


I personally prefer https://github.com/dense-analysis/ale plugin. It is in vimscript and supports almost everything (including clangd) out there: https://github.com/dense-analysis/ale/blob/master/supported-...


Is there some feature that coc.vim has that ale does not? Can someone explain coc.vim's popularity to me?

I don't understand why coc.vim is so popular, when Ale is so performant and "debuggable" (i.e. produces useful performance traces).

[long-time ale user here, I don't use clangd but I do use python-language-server, which is similar]


Generally it's because Coc has completion, snippets, and pretty much everything from the regular VSCode version of the extension built-in, so Coc can replace multiple plugins, and it works very well.


Right, but Ale does this too (replace multiple plugins, supports completion, linting/formatting).

Is it that coc.vim doesn't make you install the binaries of the tools (i.e. go-pls, python-language-server, clangd)? If so, that would be enough to explain the popularity to me.

IMO, one could make the argument that it's somewhat antithetical to vim-culture, to not understand the non-vim binaries your editor is executing.


One thing I really like in coc is I can ask to describe a symbol and it'll tell me about it in a hover thing: https://i.imgur.com/NrH0Wwz.png

Do agree that coc is probably the least 'vim-culture'-ey part of such a setup, but hey it does good things. :) I don't think you need to justify using Ale so hard and put coc down, could just use whichever you prefer personally.


Sorry if I came across that way. Agree people should use the things they prefer. :)

I'm trying to see if I'm missing something big/obvious, since coc.vim has been so popular recently.


No worries! And yeah I went through a phase a few months ago of trying out the completion packages again, it's worth just trying and seeing if you like it. Here's the relevant bits of my config if that helps: https://gist.github.com/nikki93/6ea403d3e2cbff2b3d32d4528edf...

coc.nvim has pretty much worked pretty well out of the box for many languages, and it works for me on macOS, Linux and Windows.


Do you understand how Ale works?

I use Vim not for philosophical or cultural reasons but because I enjoy the UX.

CoC's autocompletion is much more advanced than Ale. I used Ale for years.


> CoC's autocompletion is much more advanced than Ale

I thought that both are pass-throughs to other completion engines, so isn't this a moot comparison? (maybe coc integrates the completion engine, but it doesn't implement a new one, right?).

I use deoplete, but I'm not married to it (it's kind of slow when you have a big file).

    let g:deoplete#enable_at_startup = 1
    call deoplete#custom#option({
        \'auto_complete_delay': 1000,
        \'sources': {
        \  '_': ['ale', 'buffer'],
        \  'py': ['ale'],
        \}
    \})
If so, isn't the completion experience is strictly a function of the completion engine you're passing coc/ale into (ux), and the binaries that you're passing into coc/ale (completion options)?


CoC is built around the Microsoft Language Server. I wasn't able to get LSP working with Ale but perhaps things have changed since I switched.


Microsoft Language Server is a protocol. It's up to each language to have own , blessed implementation like clangd, solargraph, or gopls. The beauty of ale plugin is that it supports almost anything from scratch and as I work on a multi language projects all the time it rocks everywhere. Do you have prettier installed? Boom all your JS files are checked. Do you have gopls, gofmt, goimports? Then yeah, you can use all of those from your editor. And so on. I am usually surprised how many linters it supports. Recently I got hints when editing protobuf file. Did not expected it.

It is possible that coc.vim can do better. But I can't imagine how much better it should have be.


I do a lot of JavaScript dev, and LSP is bar none the best in class. I can jump around to variable and class definitions and do minor refactoring almost like it was C++. If Ale supports it then great. I don't care which system is used as long as it supports LSP reliably.


> The beauty of ale plugin is that it supports almost anything from scratch

this has been my experience too.

I was editing some prolog the other day, `:ALEInfo` recommended swipl. worked like a charm!

the linters covered are quite incredible: https://github.com/dense-analysis/ale/tree/master/ale_linter....

And if you read each integration file, they are quite small and comprehensible. I've never needed to add one myself, but I feel like I could if I wanted to.


coc.nvim does a lot more than linting. I know ale tries to do completion but in practice I just found the experience of using coc to be really good. It's a bunch of little things that add up. Not sure what best way to convey it -- maybe a gif? Haha. I included an example screenshot of hover type info for example. Super useful esp. as languages like C++ and Go and TypeScript have type deduction/inference. I just put cursor on a symbol and do ';h' to get type info and maybe docs. And so on and so forth.


Note that clangd is not a "blessed" implementation of a language server–there are others.


I've been using syntastic [1] for this. No server needed.

[1] https://github.com/vim-syntastic/syntastic


+1 for Ale. It has simplified my Vim life.


Same here


Have you tried it? Using CoC with neovim, neovim is instantly responsive, the only delay is that it takes a few secs for some of the CoC LSP services to be available until the language server is launched and ready. The typing experience is not impacted at all.


Neovim 0.5 (not released yet but has PPA) has a builtin LSP client that not depends on NPM. It works very well.


Is there somewhere that I can read more about this? I tried checking neovim.io and the repo but wasn't able to find anything.

edit/ Of course, Google was able to pop it out after I submit this comment... For anyone else who may be curious about how this works: https://neovim.io/doc/user/lsp.html


That's great! Thanks for mentioning this.


Qt creator is 100 MB and starts in 3 seconds. Why do you (even favourably) compare it to node?

Also, qtcreator is pretty darn good for Rust too


I thought it was obvious...

vim is lighter than qt creator is lighter than node.js + vim


I'm also not personally a fan of the model that Coc takes (although it is impressive tech).

Besides adding a Node dependency, Coc extensions are basically ported VSCode extensions with some changes necessary to make them work with Coc. This means that for every single extension you want to port to Coc, someone has to maintain a Coc fork and keep up with the upstream VSCode extension.

Personally, I just don't feel that this is sustainable.


It's actually quite good and runs super smoothly on my Chromebook, where VSCode was slow. I like keeping all of my vim stuff while also getting this.


Since this is a client-server setup, hopefully the heavy weight stuff is outside the keyboard->computer->eyeball critical path. So it should still be the nice, tight user experience associated with lightweight editor. You just have some node.js process hanging out there in your many spare megabytes of ram, occasionally sending you things.


You don't actually need NPM and CoC. I've been using pure-VimL vim-lsc[1] for a couple of years, and it's been serving me well. My config:

  let g:lsc_auto_map = {'Completion': 'omnifunc'}
  let g:lsc_enable_autocomplete = v:false
  let g:lsc_server_commands = {
  \  'c': {
  \    'command': 'clangd',
  \    'log_level': -1,
  \    'suppress_stderr': v:true,
  \  },
  \  'cpp': {
  \    'command': 'clangd',
  \    'log_level': -1,
  \    'suppress_stderr': v:true,
  \  },
  \}
This gives me code completion and other niceness.

With Vim 8.1, you don't even need a package manager, since there is one built in. Just clone the Git repo into your ~/.vim/pack/vim-lsc/start/vim-lsc/.

[1] https://github.com/natebosch/vim-lsc


+1 for clangd (not to mention clang-tidy and clang-format). On Ubuntu 20.04 clang-10 is is in the standard repositories (I’ve heard it’s well-supported on other distributions), and the setup is seamless.

clangd eats big-ass, hairy, template-heavy TUs for breakfast as concerns responsiveness, and I have yet to see it make a mistaken autocomplete suggestion or fail to find a declaration that I agreed with. It’s easily the equal in precision of the Intellisense server that some of my colleagues use and doesn’t bog down the same way. Even the method renaming is pretty solid.

For me at least it’s a small but consistent productivity increase over any of the alternatives I’m aware of and fits into your existing emacs/vim/vscode workflow.

Would download for free again.


> It’s easily the equal in precision of the Intellisense server that some of my colleagues use and doesn’t bog down the same way. Even the method renaming is pretty solid.

> For me at least it’s a small but consistent productivity increase over any of the alternatives I’m aware of

Have you tried Eclipse CDT?

Since nobody mentions it, I guess I have to. It takes some time to set it up (system paths, etc.) but once you do, it makes browsing and refactoring code a breeze.

It works much faster than Intellisense and stuff like dependency trees (call hierarchy, etc.) are much easier to navigate.

I'm using it as my main editor since 2014 or so. Have tried various alternatives on all 3 platforms (Linux, macOS, Windows), but I always go back to it for C++ dev.


I was using CDT until WFH started in March. At the time Remote System Explorer appeared to be dead-ish so I went with VSCode. Eclipse CDT is extremely tedious to configure the include paths for because they all have to be entered one by one in a text box. VSCode has a remote system extension and include paths can be entered en masse into a JSON file. I've used both with embedded projects that involve cross compilers. VSCode doesn't know MIPS processors are a thing so some of my linux driver code has unwarranted squiggles. For Eclipse the same constructs are handled by the methods it uses for any code. Eclipse supports its superior features with a lot of reindexing. VSCode supports its features with glorified searches.


I haven't used Eclipse in a long time, in a previous life when I wrote a lot of Java I would sometimes use it for the debugger.

I don't have any problem with people who want to use GUI IDEs, some are even pretty tempting (XCode with the DTrace integration is slick as hell), but I'm so married to having my development environment running on a big, always-on box somewhere under a tmux session that it doesn't make a ton of sense for me.

Plus at this point my fingers are so hardwired that I reconfigure my desktop environment to match Emacs and/or Vim text navigation rather than the other way around. Even when editing Algol/brace-type languages I can't imagine moving a lot of code around quickly without paredit-mode and friends.


it crashes early and often for me though :( Should probably switch to a more recent clangd.


I’ve been using it since the initial release when it wasn’t even its own tool, and it’s come a long way since then. There was a release that basically flipped a reliability switch and it was night and day in terms of responsiveness, stability, availability of completions, etc. Definitely update!


What environment? It's useful enough to me that I'll try to steer clear of places where it's difficult to get reliably set up.

I've used the `clang-9` chain on Ubuntu 18.04 and the `clang-10` chain on Ubuntu 20.04 and it's been absolutely seamless.


All third party libs are custom built from source, but right now I do not remember which version of clang we use; it might be older than 9. It is a big code base,


I can thoroughly recommend vim for C++ development that doesn't stretch over too many files and directories. Especially with custom include paths and a constantly changing bigger project, vim becomes almost unusable for me.

I can very much recommend QtCreator. I don't use Qt, but as an IDE it's very well made. The fact that it can also do Qt isn't even apparent when you use it on normal CMake projects and the like.

Extremely solid syntax highlighting is also important to me, which, in vim, is horribly difficult if not impossible. If I want something nested like `std::this_thread::get_id` to be highlighted properly, want macros to be a different color, want local scope variables to be a different style than class-scope or globals, vim is out of the question.

So yes, I can recomment vim for C++ development as long as you're not using a ton of libraries and are okay with most of your code being the exact same color.


I use a similar setup to the author's and coupled with ctags, I don't have any problem with massive projects and lots of 3rd party libraries.


I agree, but I'll add that vim is much easier on a project where things are well organized and laid out. Some IDEs make it easier to find classes by name or navigate by click. This can lead to disorganization when many people are involved. I've found that in such an environment, there is a fixed overhead which makes vim much harder to use productively.


I can also recommend QtCreator for C++ development! I regularly use it for my cross-platform open source projects (none of them are Qt based) and it works equally well on Windows, macOS and Linux.


Andreas Kling has used it to develop an entire operating system (Kernel to DE), so it can't be that bad.


I run QtCreator native on Raspberry Pi and it's actually usable but having Vim around for small platforms is still a good thing and basic Vi skills are pretty much mandatory since it's the "always there" editor.

On the PC I don't see much reason not to use an IDE anymore. VSCode and Eclipse are both great free options and full Visual Studio is pretty great if someone else pays for it.


>stretch over too many files

With cscope as the front-end to vim, this problem rarely becomes unmanageable... especially if you get bindings set up and/or use NERDTree or better yet vim-vinegar ..

https://github.com/tpope/vim-vinegar


Well, let me tell you how to do c++ programming with Vim. Get a Linux machine, replace the desktop with i3wm. Get a terminal emulator like urxvt and make it dark and semi transparent. Set a beautiful wallpaper. Install YouCompleteMe. Now you are in paradise :)


This doesn't spot errors for you like a language server can. And you will make errors. Which you see after twenty minutes of buildtime. Much fun. Very productive. Personally I'm back to using ides again but I'm glad something remotely viable has been made available to vim.


> Personally I'm back to using ides again but I'm glad something remotely viable has been made available to vim.

I think you might be misinformed; I've been getting code-completion and error reporting through vim for at least 8 years on C++, and I don't know how much longer before that it's been available.


I mean, I have all that. i3-gaps, alacritty, conky for transparency, etc. But for a big C++ codebase you just end up being way more productive in something like CLion. The static analysis is way way way more in-depth than something like vim can provide even with plugins.


God how i3wm changed my life for the much, much better.


This may be considered blasphemy, but I continue to use i3-gaps on my 43" 4K monitor in 100% floating mode. It actually works quite well. Of course for my small displays I use tiling mode.


Imo if you're only floating, Openbox is even lighter than i3 and works great. Super configurable too- the config file is just XML. I really enjoyed my time on it but I like tiling too much. Window-snapping wasn't enough.


Ick.

I use xmonad, despite not knowing any Haskell. I basically just copy pasted little snippets from all over the place and changed random characters until it started working.

Pretty sure I still prefer this state of affairs to XML.


Why don't you use one of the olden and golden wm's for that? i3 doesn't have alt-tab


sure it does

    bindsym $mod+Tab exec --no-startup-id rofi -show window


Rofi is great, but it's still adding several extra keystrokes for something that alt-tab essentially does in 2 (alt, hold tab till you get to a window you want, release to go to it. on rofi, you'd have to press alt-tab to invoke the window dialog, then type a portion of window name or navigate down to it, then press enter) .


> (alt, hold tab till you get to a window you want, release to go to it.

madness :) I could never manage to get to my window like that, it's alt + tab tab tab tab tab tab tab until I get where I want when on windows vs alt + tab down down down down on rofi so I don't see a lot of difference


Haha, fair enough. Also turns out tab tab tab tab works on rofi -show window (my fault for not using it much hence not knowing) so maybe it's not all that different after all!


Does i3 allow you to easily toggle floating on each window (regardless of the main mode that new windows default to) like dwm?


Yes, shift-super-space is I think the default key binding to switch the current window.


That’s exactly what it is in dwm (except that dwm defaults to using alt as the MOD(ifier) instead of super, but changing that takes only a one line patch). And you can also just use MOD-leftmouse-drag to move a window or MOD-rightmousedrag to resize (either of which change the window to floating mode if it isn’t there already), or use MOD-middlemouseclick to toggle its floating state.


If you're only using the floating mode, I would recommend trying cwm.


Terminator is my window manager -> Ctrl-Shift-E / Ctrl-Shift-O .. (Ctrl-Shift-N / -P) ..


I still use terminator out of habit, but I never tile it anymore. Terminator can't tile my browser windows along with my terminal windows, and interleaving separate shortcuts (and window groups) defeats the purpose of tiling


Browser -> fullscreen. End of problem. Tabs in the browser window are the switch point.

Terminator isn't for everyone. But it can be for anyone.


I'm not sure I follow. Are you saying you always make the browser fullscreen? Tbh I think you might be missing the purpose of a tiling window manager


Oh sure, I get the point of tiling window managers .. its just that I rarely need to leave Terminator for anything besides the odd web document or so - and that context switch is, for me, quite helpful.

But I set up Terminator in full tiled rig for everything else, and rarely every leave it. Its a delight.


add an alias to bashconfig to just enter 'g' or 'g cprogram' to compile and run

add picom with dual kawase blur https://github.com/tryone144/picom/tree/feature/dual_kawase

add rofi

add zathura and some opacity to it via picom

gg


I use i3wm.... I really never see my wallpaper. I'd have to go to floating mode to do so.


i3-gaps makes it a much better experience, in my opinion.


I love how i3-gaps, transparency etc. look but in the end I always turn them off again because it's just that little bit too distracting. But I have the choice, and that's cool.

I love me some drop shadows and a nice theme though.


How do you deal with i3wm for people who use large fonts? I use large fonts and I find that I do not have enough space in my editor to tile multiple editors.


If you haven't, you (op or readers) might try Awesome window manager. LUA based. GPL. It's i3 for us GNU-heads.


Agree with everything except the beautiful wallpaper:) That's my setup.


Only if it is a C++ programmer that writes boring POSIX CLI applications and daemons.


... instead of boring CRUD applications..


Those were already boring in mainframes before UNIX was invented.


Semantic highlighting for C++ can be achieved in Vim using color_coded: https://github.com/jeaye/color_coded

It can make a huge difference in the highlighting of the source, compared to Vim's regex-based approach. The reasoning for wanting this is to be able to soak in more information about the source without needing more text; the color alone can convey a lot of useful info about the code.


Agreed about the usefulness of semantic highlighting. Also, https://github.com/jackguo380/vim-lsp-cxx-highlight works really well with CoC and LanguageClient-neovim, and doesn't need to be compiled.


For C, default vim comes with:

  (somewhat) intelligent complete (ccomplete)

  debugging (termdebug)

  jump to definition (ctags)

  reference finding (cscope)

  file explorer (netrw)


Oh yeah, for plain C, Vim is absolutely good enough. Virtual methods and templates drive the complexity of intellisense and refactoring up to 11. The absolute worst is when you're trying to call a method on a function argument of a templated type. The completer basically has to analyse every single callsite and present you with the intersection of all types that might be used.


clangd also works C. The same setup works for C.


My alternative is to use the IDE with Vim keyboard bindings. Much nicer, full tooling support etc. I love vim keybindings but am fully ambivalent about everything else...


This always ends up in some kind of uncanny valley area for me as the editors never properly support everything.


As it stands Evil is the only Vim keybindings add-on that actually feels like using Vim. Everything else will inevitably be missing a feature or not act in exactly the way you expect, leading to disappointment. That and you also lose out on Vim extensions.


Evil is very good, but moving to Emacs from vim was not quite the smooth ‘just use evil and you get the best of vim with the power of Emacs’ experience that people say, at least for me.

I found it needed some extra configuration before it felt like stock vim.

C-u isn’t bound to "scroll up" by default with evil, for example. You have to (setq evil-want-C-u-scroll t). That took a while to figure out and I expected it to work that way by default.

Then you have to (setq evil-want-keybinding nil) and install evil-collection and evil-magit to be able to use vim movements in other Emacs buffers.

Or you have to learn Emacs shortcuts and just use vim for editing, but that feels awkward for a vim native.

As an Emacs newbie I still find it unsettling that documentation for packages and for Emacs itself all uses Emacs-style shortcuts. Of course it couldn’t really be another way, but I either have to learn those or remap things to vim-style leader bindings. It makes vim usage in Emacs feel a little uncanny at times.

I could use a distro like Doom which has it all wired up for vimheads already, but then I’m learning someone else’s shortcuts and system, which takes away from the point of Emacs a little for me (the idea that you make it your editor).

Maybe it gets easier with time. If any other vim users made the move to Emacs I’d love to hear some tips!


My advice at this point is something along the lines of "use Doom," because all that time you would normally put into wrangling evil into doing what you want it to would instead be offloaded onto another person who makes wrangling Emacs in general his hobby.

It's like the small things such as binding C-u to scroll up by default are taken care of for you out of the box. How many people who use Evil who are already familiar with Vim are going to not end up setting that configuration option in plain Emacs at some point? (Maybe those who use page up and page down, but not even those commands do the same thing as C-u and C-d, at least in Evil.) Everyone else will have to add that line to their config, and that quickly gets unmaintainable if what you actually want to do is focus on work instead of building a proper Emacs framework. So it is set for you already.

Doom is basically that for Evil configuration and several thousand other things.

One downside is having to undo some of Doom's built-in things if they're annoying. One example of this is having to insist that it uses a specific set of completion handlers and not globally set a hardcoded list for every mode. Still, the amount of time you'd have to do this is less than the amount of time it takes to build 30% of Doom for just the features you want from scratch.

And yes, it is at times a sad feeling needing to fall back on someone else to do the hard work for you, but the realities of work and limited free time essentially dictated that decision for me.


Thank you, that's helpful, and I recognise a lot of the pain points and pluses there.

I started with Doom, loved it, but wanted to understand Emacs better so ended up writing my own config.

I now understand Emacs a _little_ more, I know what every line of my config is doing, and there isn't an extra layer of abstraction or opaque bash commands I have to periodically run. I also feel more comfortable that Emacs with a home-grown config will last me 10+ years. It's incredible what Henrik has achieved and the level of dedication and support is astounding, but I wonder how sustainable it is as the community inevitably grows.

Rolling my own setup has certainly made me appreciate Doom a whole lot more, though. And it's hard to shake the feeling that I could spend a year or two just hacking on Emacs to get half of what Doom offers.

It's like the trap of wanting to get into game programming and finding yourself writing a game engine instead of a game. (I picked up Emacs to learn Clojure and other Lisp dialects better.)

It's also a little silly to have an expectation that I need to understand everything that Doom does behind the scenes. I don't have that expectation with Emacs itself, or with IntelliJ or vim, or VS Code…

Maybe the answer is to just read the (smallish) Doom codebase to understand it better and contribute however I can, be it in Discord, with cash, or PRs. And get back to hacking instead of hacking Emacs…


Or you have to learn Emacs shortcuts and just use vim for editing, but that feels awkward for a vim native.

FWIW, I went with this approach and found it to be the sanest/best for me. The attractiveness of vim is the text editing experience.


While I prefer a simple editor, in the instances when I'm forced to use an IDE, I'm glad that VIM keybindings are almost always available. E.g., vsvim works quite well in Visual Studio. If I clinch my eyes it's almost like being at home.


Stupid question: who controls the language server? If I have multiple projects or multiple branches of one project or even just multiple build folders for different configurations, how do I tell the language server what I am currently working on?

If I put the setup in my home directory, I am limited to a single setup (compiler, stdlib).

If I put it into the project directory, I am limited to a single build for, and potentially a single branch, and I will have multiple instances of the lsp running if I stop working on one project.

If I put it into the build for, which seems sensible, how does the editor decide which server to run or ask?

It seems to me that I need some sort of project manager that acts like a lap proxy and then resolves these issues. Do I need to write one myself?


What I do currently is run an LS per repo with its configuration stored in the repo, so:

  + ~/repos/repoA
  | - CMakeLists.txt
  | - compile_commands.json -> ../../build/repoA_config1/compile_commands.json
  |
  + ~/build/repoA_config1
  | - CMakeCache.txt
  | - build.ninja
  | - compile_commands.json
  |
  + ~/build/repoA_config2
  | - CMakeCache.txt
  | - build.ninja
  | - compile_commands.json
etc. for repoB, C, ...

That said I'm thinking on flipping it around - keep the LS configuration in the build folder, and symlink the source folder in it. That way I can have several different configurations in effect at once and switch between them easily. Currently I have to change where compile_commands.json points to if I want to change YouCompleteMe's completions.

Your editor should manage the language server and you should just have to provide the configuration it expects in the directory you start it in.


Not a stupid question! The editor/plugin manages the language server process, and starts it as necessary with whatever project config it found for the file being edited.


as to how clangd sees your current translation unit, it comes down to the compile_commands.json (which is per-TU settings) or the more general compile settings in the config file(s) (https://clangd.llvm.org/config.html). If you need to change your TU settings, you could have a simple scheme that symlinks compile_commands to different files depending on build type and then restart the server. I've not typically needed to do this (I tend to just stick with a debug build compile DB...), but it's something you could do pretty easily.

There is one clangd process per editor process. If you have multiple projects with distinct compile_commands you might be able to come-up with a scheme to switch between DBs and relaunch clangd. Alternatively, you could try merge all compile_commands together, but I'm not sure the effort would be worth it -- just running separate vims seems like it makes the most sense to me.

For switching between branches, you can typically regenerate the compile commands DB pretty easily (if you use cmake...), but it's really only necessary if there are big differences in files and/or compile settings between branches.


I too would love a plugin for this.. I'd like to run the LSP server in a Fedora toolbox, then some sort of property in the project's compile_commands.json or .vimrc that tells it where to find the LSP server. (Fedora toolbox mounts your home directory, so paths etc shouldn't be a problem.)

At the moment, I run everything (toolchain, LSP server, nvim) in a toolbox. Works well, but it feels unecessary to have a copy of vim in every container.


Well, quite irony is that the best support I ever saw was... JavaScript and Node. As every such project has node_modules with dev dependencies, so everything can use project local dependencies. Ale does that.


I use a similar approach and setting for c++, I purchased clion for two years and rarely used it, vim is just handy and light-weight, I will probably use clion when my project becomes huge, until then, vim is absolutely enough.

vim nowadays can find all the headers, do linter and auto-fix and auto completion, and when you're coding, you rarely need move the mouse at all, vim 8.2+ is itself a modern IDE inside a terminal, again, light and fast, I enjoy it.


I tried this. It is basically a slightly improved VSCode at this point.

Basically, most the slowness/bulkiness of IDEs does not come from the text editing portion.


What's the advantage of using a LSP over, say, ctags and cscope ?

I currently am using that, along with the https://github.com/stefandtw/quickfix-reflector.vim for quick refactors, and it seems to work fairly well.

Is it because of method signatures or is there a killer feature that I'm unaware of ?


cscope looks like dead project with no support of the recent versions of C++(14/17/20)


I wish I could find (or create) a working LSP setup for the Java code base at work. It consists of multiple projects, tied together by a Gradle build script. IntelliJ just groks the build.gradle and Eclipse can also import it.

Is there an LSP server that can do something similar?


At one point I tried embedding a language server in a running IntelliJ process. It kind of worked, but a few problems led to me getting tired of maintaining it:

- Constant API updates to IntelliJ internals requiring updates to the extension.

- The need to run a full copy of IntelliJ in the background, and breakage in the copy leading to requiring a full restart.

- A lot of concurrency problems I didn't understand because by necessity it required going deep into IntelliJ's codebase.

- I was no longer using Java in my work environment or for personal projects, so I had no need to use IntelliJ.

But despite this, the repo stands as the most-starred one I have. People are still starring it even though I haven't made changes in over a year and a half!

https://github.com/Ruin0x11/intellij-lsp-server

So it sounds like this is a thing people would use, if someone wants to take up the maintenance burden.


IIRC, Vim has some kind of builtin support for Eclipse for Java development, have you tried that? I admit I haven't really looked into it, just seen it mentioned while reading the manual.


With neovim 0.5, you can drop two dependencies,

Plug -> built-in vim packages CoC -> built-in LSP client


You could drop Plug even with the existing stable release. Native packages have been supported since Vim8 and NeoVim 0.2


Do you get semantic highlighting though? That was one of the big reasons just using an LSP client wasn't enough.


For that I just installed vim-polyglot. Its a big ole collection of syntax and indent rules


Oh checkout nvim treesitter


I really like using TabNine for completion which does a sort of AI-autocomplete - the suggestions are usually more than just the next token, and sometimes are scarily good.


My first advice for anyone who wants to use Vim for C++ development would be - don't. I've used exclusively Vim for over 10 years and it's too comfortable to switch to anything else, so I'm losing out on a lot of productivity, or at least that's what my colleagues, who have never used Vim, claim.

Pithy claims aside, it has been an interesting journey actually using Vim for producing C++ code for large projects. There's a strong DIY element and you end up with a setup that's much more customised than a vanilla IDE - on the one hand giving you a certain degree of comfort in your work, but on the other a lot of what you do is unportable to other people. The language server protocol has been a pretty good development, I'm keeping an eye on what comes out of those efforts, though I'm not using one personally right now.

My current setup consists mainly of exuberant-ctags for static indexing, YouCompleteMe for intellisense and simple navigation, rtags for rich search and light refactoring and fzf for searching. As to why I ended up settling on these plugins:

- ctags:

Absolutely essential. Yes, a full semantic index straight from the compiler is better, but ctags is more than good enough for just telling you "where is this defined". When paired with fzf, you can type part of the tag, space, part of the directory and you'll get all tags in that directory. That's due to fzf doing super simple substring matching in the TAGS file's lines based on your query, there's nothing smart going on here. This tool is also very good when you are developing multiplatform software, because the compiler cannot see all places where a function or class is defined, since you have one definition per platform. Technically being able to query a plethora of language servers, one for each configuration, would be ideal, but we're not there yet, and such a setup sounds way too fragile for my taste.

- YouCompleteMe:

Aside from C++, it provides amazing completion support for many other languages. It can even deal with java project files, if the readme is to be believed. Other than for C++, I mainly use it for python. It's also good in plaintext files for completing words and file paths. I really love its substring matcher, just type gTFBT to get "getTheFooBarThing". Downsides: 1. if your build system cannot produce a compile_commands.json file, you will need to write some python code to specify compilation flags; 2. compiles each file individually, so if some of your headers aren't freestanding, you'll get spurious errors when editing them.

- rtags:

Basically a language server from before the LSP protocol existed. Mainly developed for Emacs, but the Vim integration is good enough. Continuously indexes your source based on a compile_commands.json file. It can show you who calls a function or uses a variable, class hierarchies, virtual method overloads and more. I've seen it get confused if you jump branches and require you to delete and recreate the index, but I haven't experienced that lately.

Apart from those I use a bunch of standard productivity plugins like unimpaired, surround, nerdtree, etc. etc. Vim 8's gdb integration has been very welcome, too. I struggled to find a good interface to gdb previously, as everything seems to want to be Visual Studio and give you a restricted clicky interface, whereas I just wanted the current vim buffer to be synchronised with the instruction pointer and to write gdb commands directly.

I don't feel like I'm substantially slower in Vim than my colleagues in other editors and IDEs. Colleagues across the company use Vim, Emacs, VSCode, QtCreator, and Code::Blocks. The Windows developers are all on Visual Studio naturally. I haven't noticed being slower than any of them. The above plugins are enough for the odd rename-refactor I have to do, and anything more substantial is so infrequent, that doing it manually doesn't really have an impact. Also, developing on Linux, I always feel like any graphical application will just disintegrate or cause an unrecoverable freeze in the graphics driver at any random keystroke.

Back in the day I had to make do with just ctags, cscope and debugging straight from the commandline, lol. I do believe that Stallman's refusal to allow easily plugging into GCC's AST, like one can just use clang for indexing, held back C++ development tools on the Linux platform significantly. Eclipse's CDT, KDevelop, Anjuta, Code::Blocks, NetBeans, etc. - they all suffered from having to write their own C++ indexers that were always inferior to getting semantic information straight from the compiler. I'm extremely grateful to the open-source community for the continuing work on development tools, and try to donate where I can. Watching the development tools landscape change over the years has been interesting - things don't so much improve, as they evolve chaotically with an overall trend towards improvement. Like anything else on this platform. So far many IDEs have come and gone, but Vim is eternal.

I will say that using Vim is entirely up to your taste, it doesn't seem to be substantially faster or slower than an IDE, so use what you like. It is much cheaper than Qt Creator or CLion (AFAIK for both you need a license to develop commercial software), so that might be a factor for you. Companies tend to have a big Windows development team, with a few Linux developers, so they buy bulk Visual Studio licenses and individual Linux IDE licenses, making the latter end up costing more per developer.


> It is much cheaper than Qt Creator or CLion (AFAIK for both you need a license to develop commercial software),

Qt Creator is GPLv3 (https://github.com/qt-creator/qt-creator/blob/master/LICENSE...). You can do whatever you want with it.


Ah, I see. I last looked into using Qt Creator around 2015 and it seems this license change is from 2016. The company I worked for at that time said from their reading of the license we need a commercial license and asked if I could please pick something else. If I had just checked it out a year later, hah.


I use vim8 plus an assortment of plugins and it works quite well. I use rtags, vim-rtags, vim-clang, vim-fugitive, vim-polygot, vim-cpp-modern on a large project. I'm also looking into vim-lsp instead of rtags+vim-rtags now. If you are a vim enthusiast then it can work, but it can take some time to go through a few different IDE-like methods and also to setup/config/map things. Onivim2 is also something to look at.


Is there a LSPs in a box somewhere yet?


Currently I think the coc.vim plugin is as close as you can get. It has installers for LSP servers and VSCode extensions.

You might also have good luck with a curated vim distribution such as SpaceVim[1], where everything should be pre-installed for you.

Later, NeoVim 0.5 is going to have LSP out of the box[2]. So things are very positive.

[1] https://spacevim.org/

[2] https://neovim.io/roadmap/


I didn't think setting up YCM was too bad. It also uses clangd as the completion engine for C++.


What I really love about vim lately: Termdebug.

Its such a joy to have cscope bindings and gdb-based debugging direction within vim itself.

This has been a joy to re-discover after forgetting that vim has a great integrated debugger now. I keep forgetting it, but man has it been great to use lately.


Has anyone used VsCode for C++/CMake development? What was your experience?


I'm primary Emacs user with LSP mode setup. But sometimes, Emacs performance just triggers my frustration enough to use VsCode.

To me, VSCode is much better experience from performance and LSP integration perspective. Everything works pretty much as you would expect. I use `ccls` and `goto-symbol-stack` for better tag browsing -- which gives pretty close experience to Emacs "M-." or Vim's "C-[" and go back shortcuts.

I don't use any CMake extension. You can basically create tasks and assign one of them as build. I just use those task to run the CMake commands, or my own scripts which sync and compile code remotely.

There are some other awesome plugins (I use Git ones), which are incredibly good.

If you work on Windows, I hear integration with Linux Subsystem is excellent, and there is some other features for general remote development that I often try.

Often, eventually after a day or two of use, I would still get back to Emacs, because what I absolutely miss is years of conditioning and customizability of Emacs. The keybindings are exactly how I want (and they make sense), window splits and workspaces (are in my opinion superior to VSCode), things popup and close when I need them and keybindings around them are straightforward.

Bottom line is, if you are hardcore Vim/Emacs user --

(1) you'd probably appreciate the convenience, excellent performance with LSP and bigger files, things working out of box, font sizes/colors being consistent, and nicer UI around code browsing. (2) At the same time you'd miss certain essential things that are heavily engrained into you. Lot of things will be good, but not good enough -- specifically related to keybindings/window splitting/buffer management.


Using it for about a year now on medium-sized projects and liking it. Definitely set up the clangd extension as also mentioned elsewhere. Extension ecosystem is great in general.


Works pretty well with the C++ extension and the cmake-tools extension. Though at some point I ended up just swapping to invoking CMake from the command line.


I haven’t found a good CMake linter, do you use one?


Just no


Closed the page when I saw cmake mentioned


What should we be using? I’ve had nothing but trouble with Bazel and Buck (I’m a Buck committer). autotools is notoriously painful. Hand-written makefiles can be nice for smaller projects but get cumbersome with bigger projects.

What am I missing?


For small personal projects I started using dds: https://github.com/vector-of-bool/dds

It's still very very young and in development, so not ready for prime time, but it "just works" and doesn't make me feel stupide the way CMake does...


Thanks for the pointer, I'll take a look. CMake is definitely one of those tools where I look at the last project I was working on when I can to remember how to do stuff.


I would recommend GN (https://gn.googlesource.com/gn/)

It has almost the same syntax as Bazel, but its implemented in C++.

Super-fast and tend focus on Ninja build files.

I've even created a fork that works for Swift here and it works pretty well.

Its the meta-build project for Chrome, so its optimized for big projects with a lot of dependencies. I dont actually understand why is not much widespread giving the bad shape of meta-build systems (like CMake).


Cmake is used to generate the json file that clangd uses to do the autocompletion. You can use other tool, like meson, or even create the json file by hand.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: