IntelliJ’s timeless Tips and Tricks

Fedor Korotkov
9 min readFeb 19, 2015

--

Note from 2022: This post is still relevant! Please enjoy!

I want to start with a few disclaimers. I’m a huge fan of IntelliJ and my opinion is definitely biased. I even worked at JetBrains for two years. This post is for active IntelliJ-based IDE users who want to improve their productivity by learning a few neat tricks. This post is not intended for beginners.

I’ve been doing Scala and Java for a while and most of the examples below will be in Scala or Java. But one cool thing about IntelliJ is that all IntelliJ based IDEs share the same user experience regardless of the platform. All the refactorings are working the same for any programming language you are using. Debugging experience is the same as well.

Most of the content below will be about different actions you can use for navigation and editing. Debugging, working with VCS won’t be described in this post. Each one of the actions has a corresponding shortcut. I will provide a name of an action as well as a corresponding shortcut for Mac OS X keymap. The default keymap on Mac is Mac OS X 10.5+. But I prefer Mac OS X because I think it’s more efficient and shortcuts are easier to remember. Also all shortcuts are pretty much the same on Windows and Linux (just replace ⌘ with Ctrl, ⇧ with Shift and ⌥ with Alt).

How IntelliJ works?

I want to start with a short overview of IntelliJ architecture. I consider it a bad practice to use something like a blackbox without knowing how it works.

IntelliJ is a platform with a bunch of different plugins. All IDEs like IntelliJ, Android Studio, PyCharm, RubyMine share the same core. The only difference is in set of plugins. PyCharm has only plugins for Python developers, RubyMine for Ruby developers, etc. Further I will call all these IDEs just IntelliJ.

IntelliJ has something called Virtual File System (VFS), an internal abstraction to handle different kinds of file systems (local, mounted, etc.). For every file VFS stores all changes for a long period of time (depends on overall amount of changes to store). That’s how Local History is working. So if Git messed up your files only local history will help you. It has saved me dozens of times.

Local History for tests folder

For every supported language IntelliJ has a parser. It builds an abstract syntax tree (AST). IntelliJ stores serializable representations of stripped ASTs called stubs. It allows not to reparse a file on every read. These ASTs make IntelliJ the smartest IDE. A lot of people are complaining that IntelliJ is indexing all the time. Now you know what it is doing. It is building ASTs and stubs, indexing these trees to collect all kind of information such as class/function definitions, just words, etc.

IntelliJ provides an API for plugins with a lot of different extension points plugins can use. Each plugin registers a lot of extension points and when, for example, IntelliJ needs to complete a reference name it will iterate through all registered completion contributors and call them even if they won’t contribute anything.

Hint: To speed up IntelliJ — just disable useless plugins. For example Database Integration, Subversion, ANT if you are not using them. Go through all the plugins and disable the ones you are not using.

Agenda

First of all we are going to learn how to navigate across a codebase. Then we are going to learn how to edit sources.

Navigation

Goto by

Because IntelliJ parses source files and indexes them it provides not only navigation to a file by a filename but also a few more intelligent navigation actions:

  • Goto by File Name ⌘⇧N
  • Goto by Class Name ⌘N
  • Goto by Symbol ⌘⌥⇧N

Goto by Symbol basically means “Goto to any definition” like fields, functions, methods and of course classes as well. I personally use Goto by Symbol to find an util method. In a huge codebase it’s very likely there is already such util function. For example if I want to traverse files recursively starting from some root folder and I’m in IntelliJ codebase that uses Processor class all over it. I can assume that an util method name should contain words ‘process’, ‘file’ or ‘files’ and ‘recursively’. It means I can just type ‘prFileRec’ and IntelliJ will suggest me methods with names that match the conditions above.

Note that IntelliJ assumes CamelCase is used as a naming convention and matches method names accordingly. Internally this feature is called “CamelHumps Matching” and you can check an implementation here.

Going even further we can assume that this method should be in an util package or in a class named BlaBlaBlaUtil. To filter out results in this case we can just type ‘util.prFileRec’ instead of just ‘prFileRec’.

It works the same way with Goto by File Name action. You can filter files in a particular folder by adding a ‘folderName/’ prefix.

Recent Files

Now when we can navigate through project files. We can easily access recent files with Recent Files action (⌘E).

And the coolest part of IntelliJ based products is consistency. Same concept is used in many places. For example you can use CamelHumps Matching in Recent Files Dialog too as well as in many more places (basically you can filter any collection representation).

Recent Files Dialog

Basic Navigation

I assume everyone knows Back (⌘⌥←) and Forward (⌘⌥→) actions which allows to jump to previous and next caret locations. But there are a few more actions like Previous Tab (⌃←) and Next Tab (⌃→). And my favorite less known super useful action called Last Edit Location (⌘⇧Delete). It allows you to jump to the location you were editing last. Just imagine you are writing some new awesome function and started digging in a library to find a proper way to implement it, you finally found it and now you need to find this place you were writing your super duper function. And now you just one shortcut away from it.

Structure View

Now we know how to navigate across different files. How to find a file that contains our class definition, how to find a particular file in a particular folder, etc. But there are quite a few navigation actions we can use to navigate in a file. And the first one is Structure View (⌘F12).

IntelliJ shows this structure using previously built AST for the file.

Type Info and Declaration (Scala Specific)

One of the first features of any IDE everyone learns is going to a declaration of a method/function/class (⌘B or ⌘Click). But Scala plugin for IntelliJ provides some useful functionality regarding type information.

For example in Scala you can omit certain type annotations and Scala itself will infer types for you. It is super handy to write less code and also it’s easier to read the code that way. But sometimes you want to know the actual type of a variable. Type Info action (⌃⇧P) will help you in this case.

It even works for expression!

Ok. Now you see the type of a variable but what if you want to navigate to the definition of the class? Type Declaration action (⌃⇧B) will do exactly what you want. And it works for expressions too!

Quick Definition

While navigating through your code you are ending up opening a bunch of useless tabs in IntelliJ. By default it’s just 10 most recent tabs. Of course you can change the limit in Preferences -> Editor -> General -> Editor Tabs. But Quick Definition Action (⌘⇧I) will show the definition of a class/method/field etc in a pop-up and not in a new tab.

It also works everywhere like most of IntelliJ actions. For example when you are in Navigate by Class Name dialog.

Usages

IntelliJ builds an index of all occurrences of a word and when it tries to find usages of a symbol let’s say function foo. IntelliJ will check all occurrences of “foo” word and will check if Navigate to Definition action actually navigates to the symbol you are looking usages of. There are a few actions that will help you to find usages:

  • Find Usages ⌥F7
  • Find Usages in File ⌘F7
  • Highlight Usages in File ⌘⇧F7

Bookmarks

This one is my personal favorite. Put a bookmark with F11 and search for one with ⇧F11. Simple as that.

Class Hierarchy

IntelliJ builds ASTs and analyzes them. IntelliJ knows about the structure of files and about hierarchy of classes. You probably already noticed that blue and green line markers in an editor you can click on to navigate.

There are also two actions that can be used in place:

  • Super Method/Class ⌘U
  • Implementation(s) ⌘⌥B

Hint: Quick Implementation action (⌘⇧I) works here as well.

Editing

Usually editing takes less time than actual exploring a codebase so this part will be shorter.

Inspections

IntelliJ has hundreds of various inspections. IntelliJ analyzes your code and provides warnings with fixes in place. You actually can refactor your code without actual editing it just apply a quick fix. So if you see a highlighted piece of code just press ⌥⏎ to apply a quick fix. Look at an example of a spell checking inspection below:

After pressing ⏎ IntelliJ will suggest to fix the typo:

Note: IntelliJ runs only light inspections on the fly. If you want to Run all available inspections use Analyze -> Inspect Code action.

Rename Refactoring

IntelliJ finds all usages of the symbol with Find Usages action and replaces all found usages with a new name. Because Find Usages action as it was described above actually tries to resolve a reference, Rename Refactoring (⇧F6) is much smarter then a regular find and replace. Rename Refactoring also suggests to rename getters, setters, Test Classes and many more related symbols.

Extend Selection

Because IntelliJ builds ASTs of the files it allows you to select a node in AST and extend the selection to the parent. It allows you to select logical blocks like an expression or a group of statements. Note: you can invoke Extend Selection (⌘W) action and Shrink Selection (⌘⇧W) action multiple times.

Introduce/Extract Refactorings

IntelliJ has a lot of Refactoring actions, most of them are listed in Refactor menu. Many of them operate with a selected fragment of code. For example:

  • Introduce Variable ⌘⌥V
  • Introduce Field ⌘⌥F
  • Introduce Parameter ⌘⌥P
  • Extract Method ⌘⌥M

They become extremely useful along with Extend Selection and Shrink Selection actions.

Surround With

Surround With (⌘⌥T) action works with statements and helps to surround them with another statement.

Override/Implement methods

IntelliJ knows not only about hierarchy of the classes, but also about all the methods that you can override or should implement. Pop-ups for Override Methods (O) and Implement Methods(I) automatically show only methods eligible for the action.

Thank you for reading and feel free to text me here or on Twitter if you have any questions and/or suggestions.

--

--