Other than my command shell, CLion is the most powerful tool in my arsenal. This is first post in a series about how I found CLion and it’s most essential features for embedded C code development. In this post I talk about CLion’s most basic features, but in future posts I’ll talk about the plugins I use and more specifics to embedded code development.
A Little History
Once upon a time a friend introduced me to the Visual Assist plugin for Visual Studio, an event that forever changed how I developed code. Having come from the world of MPLAB and IAR, I had no concept of code refactoring or any ability to search my code other than Control + F
. Visual Assist opened my eyes to the possibilities that were at my fingertips. Eventually I discovered the joy of working with Unix command shells and fully embraced my MacBook. This posed a problem for me, since Visual Studio only ran on Windows. And so I began the great search for a new development environment, a process that took years and ended with CLion. I tried Atom, Sublime, VSCode, vim + ctags, and several others, but nothing really matched the power of Visual Assist. The one thing I learned from these other editors though is that Visual Studio is ugly, clunky, slow, and bloated. I needed a better tool, one which combined the power of Visual Assist with the beauty and elegance of a modern editor. Enter CLion.
CLion is hands down the best C code editor on the planet. It’s fast, beautiful, stable, keyboard centric, and flush with features that make code development a joyful experience. I honestly look forward to sitting in front of my code each day. Here are a few features that I can’t live without.
Note, the keyboard shortcuts listed here are for OSX. Check out JetBrains for Windows and Linux.
Refactoring
- Rename symbol:
SHIFT + F6
- Find usages:
CMD + ALT + F7
This is the number one feature that is missing from other tools like Atom, VSCode, etc. With a keystroke, you can rename any symbol (function, variable, typedef, compiler switch, etc) across your entire application. Because CLion compiles your code, it also understand scope, which means that if you rename a variable in a function, the change only applies to the usage within the function. If you rename an element of a structure, that field gets renamed wherever it’s used, no matter how deeply it’s buried.
After renaming symbols, the next most powerful tool for refactoring is the ability to instantly find all usages of a given symbol. I rely so heavily on this feature that I literally feel blind without it.
Traversing the call stack
- Go to definition:
CMD + B
- Go back:
CMD + ALT + LEFT
- Go forward:
CMD + ALT + RIGHT
These days many editors have the ability to go to the definition of a function, so I consider this the minimum feature requirement for a modern editor. Generally you’re tracing through the code, you come across a function and need to jump into it’s definition. You might do this several times as you’re going deep into the call stack. The problem with most editors is that you eventually lose a sense of where you are in the code and have no way to get back to where you started. In CLion this is not a problem, you can easily navigate back up the call stack and keep working from where you left off. Not only can you navigate backwards, you can also navigate forwards. This makes it super convenient to move up and down the call stack.
Basic navigation
- Open recent file:
CMD + E
- Navigate to header from source (or vice versa):
CMD + ALT + UP
- List symbols in file:
CMD + F12
- List symbols in project: Double tap
SHIFT
- Navigate to prototype from definition:
CMD + B
For folks coming from old school editors, this will totally blow your mind. Keyboard file navigation is something I learned from VSCode, but the implementation in CLion is super slick.
Once you become familiar with a code base you generally know two things, the approximate name of the files in the project and the approximate name of the symbols in the files (functions, defines, etc). I say approximate because it’s really not important (or a good use of brain cells) to remember the exact names of every file and function. For example, let’s suppose I want to navigate to the initialization function for my audio pipeline in my speaker firmware. To get to this function super fast all I have to remember is that the file in question had ‘audio’ in the file name and the function had ‘init’ in the function name. In CLion I can navigate to this function so fast that my brain barely has to do any work at all before I’m there. I’ll press CMD + E
and start typing ‘audio’, but probably ‘aud’ is sufficient. In the dropdown list I’ll arrow down to AUDIO.c
and hit enter.
Then I’ll press CMD + F12
to list symbols in this file and start typing ‘init’. CLion automatically filters the list as you start typing. Arrow down to ‘initializeAudio’ and hit enter.
On a side note, you can navigate from a header file to it’s associated source file (or vice versa) with ALT + CMD + UP
. You can also navigate to a function prototype with CMD + B
, if your cursor is on the function definition.
Code completion
One of the things that drove me nuts about Atom and VSCode is that their code completion isn’t very good. Those tools don’t build your code, so their code completion is based on what you’ve previously typed. Not terribly useful. CLion builds your code and understands how symbols are linked together. This is how you get lightning fast and accurate suggestions as soon as you start typing.
Code completion works just as well in nested structures.
Plain old CTRL + SHIFT + F
Every now and again you have to resort to a good old text search. Again, CLion takes this a step further. I’ve never seen a more useful implementation in any other editor. Just try it and you’ll see what I mean.
Moving objects
- Move object up:
CMD + SHIFT + UP
- Move object down:
CMD + SHIFT + DOWN
This is a pretty cool feature that I used to use a lot before I discovered the power of the VIM plugin, which I’ll talk about in another post. Because CLion builds your code, it understands that things like functions, if statements, switch cases, etc are objects that have starts and ends. In CLion these can be moved up and down in a source file without the need for cutting and pasting. For example, suppose I have three function definitions in a file called A, B, and C, and they’re defined in that order. To reorder these functions so that they are defined as B, C, A, all I have to do is navigate to the definition of function A and press CMD + SHIFT + DOWN
twice. Pretty cool. This works with any object. What I use it for most often is moving a single line of code up or down within the scope of a function. But like I say, now that I use VIM in CLion, I don’t use this feature very often anymore. But, if you’re not yet indoctrinated into the cult of VIM, then this is still great to know.
Wrapping up
Well that’s it for now. My next few posts will be about building embedded projects with CLion and extending the power of CLion with VIM. Stay tuned!
Source code
The code I used for this post is a Bluetooth stack developed by Texas Instrument.