This review is for the Professional Edition of PyCharm 3. It includes screenshots and sound-free video demos of PyCharm features. I will try to cut straight to the point while offering some tips from my experience.
With structural completion, PyCharm displays a modal dialog containing fields of an object's class first, followed by fields and methods of its superclasses and mixins. Once you trigger this completion dialog, you can type to filter the selection.
Word expansion is a new feature in PyCharm 3 that lets you complete symbols anywhere in the file, including comments and docstrings. Rather than being aware of a structure or object, the completion works through simple text matching. It's great for writing documentation.
What I mean by Code Navigation is the use of keyboard shortcuts that jump you to the definition of a symbol. PyCharm has a couple of these features — pretty much everything you'd hope from a Python IDE.
The first is Goto Symbol, which opens a popup similar to the one provided for completion of fields on an object, except that it includes symbols across the entire project. I use this when I know where I want to go by name.
More often I use the Goto Declaration feature. This is available by moving your cursor over a symbol and firing a keyboard shortcut (I think it's also available as a mouse action.)
I use these features all day, every day to review APIs and docstrings of library code I’m using. It’s indispensable and works consistently.
This is the feature I’ve had the most trouble getting other editors to do well. Vim and Sublime Text with the rope library and some integration tweaks — or PyDev in Eclipse — can sometimes give you decent navigation. However, I’ve used all of these extensively and they all failed every day. Furthermore, it was not always clear why they failed. The end result? Sadness, anger and a sense of Primitive Humanity falling to darkness.
With PyCharm, I don't even notice this feature anymore. I just expect to get wherever I want to go, and I do.
Vim Emulation with IdeaVim
I've discarded a lot of editors that claimed to have Vim emulation either built-in or through a plugin. PyCharm's is the best.
The ex command line is decent, block cursor and line highlighting look great, modal editing is responsive and IdeaVim supports all of the motion commands I use on a regular basis. There is a good list of all the Vim features the plugin supports.
However, all is not chocolate and roses. Custom bindings work more like they do in Emacs and Sublime Text than in Vim because there is no concept mode-specific bindings or a leader key. You end up combining Control, Command, Option (or Alt, Win, etc. on PCs) with various keys to produce unique sequences.
So, that's a drag, but I was once a hardcore Vim user and here I am, almost two years of PyCharm later.
See the Keyboard Shortcuts section for a more in-depth review of the keybinding system.
In my experience, JetBrains is committed to Vim emulation. The company releases regular updates to IdeaVim, and the plugin has become much more feature-rich and reliable over time.
PyCharm’s test runner helps me achieve an uninterrupted flow state while writing tests. It supports all of the testing libraries I've thrown at it, including the Django test runner, nose, Unittest and py.test.
For what seems like a simple feature, it has a huge impact. I’ll try to explain by talking about my experiences with other editors.
You can get a nice system going with Vim or ST 2, but ultimately your workflow is something like “write tests, switch focus to command-line interface, execute the last command or type a new command to run a specific test or suite, examine output, switch focus back to editor.”
After using PyCharm, I find this workflow primitive and distracting.
In PyCharm, if I want to run a test I’m working on, I hit a keyboard shortcut that detects the test method or class my cursor is within and offers to run or debug it. In the dialog box that opens when I hit this keyboard shortcut I have several options for how to run the test, based on the test runners PyCharm finds for the configured interpreter (nose, Unittest, py.test, etc.). I can type the number of an option to run it.
Test output appears in a panel at the bottom of the window. If the test raises an exception, PyCharm converts each line of the stack trace into a hyperlink that opens the file in question at that line when I click on it.
Seems simple, right? After using these features for a year, I can’t live without them. Here’s why:
- After the tests run, I can hit a keyboard shortcut to jump between the tests I ran (useful if some failed)
- When I'm writing code, I can hit a keyboard shortcut that reruns the last test immediately (no context switch required)
- I want to give JetBrains $100 just for turning lines of a stack trace into hyperlinks
At first I wasn’t super impressed with using PyCharm’s graphical debugger, compared to my experience with
ipdb. It’s grown on me over time, though, and now when I try to use
ipdb I feel that old sadness for Primitive Humanity.
PyCharm lets you set a breakpoint with the mouse or a keyboard shortcut. When you run project code with the debugger, either using a test or a Run action like the Django development server, a special toolbar window slides into view with the debugging context when execution hits your breakpoint.
You can then interact with each frame on the stack by clicking on a list of frames in the debugging panel. A "Variables" tree lets you view the state of each variable in the scope of the current frame. You can also run arbitrary code within the scope of the frame by using the “Evaluate Expression” command (available via keyboard shortcut), or run an interactive console session similar to
The Evaluate Expression command opens a modal dialog box. The “result” portion of the dialog shows the return result of the expression after you click “Evaluate.”
You see the exception class of any exception raised by the expression, but not a stack trace. “Code Fragment Mode” lets you write more than one line for your expression. The interactive console is useful because you can see standard output (you can't in Evaluate Expression). However, while there is a keyboard shortcut to launch Evaluate Expression, I haven’t found one for the interactive console, which seems to require two mouse clicks (ugh!).
In summary, I like the PyCharm debugger better than ipdb because it helps me to avoid switching contexts. With Evaluate Expression, I can remain in a flow state while I debug failing tests, using only keyboard shortcuts. This beats switching to a terminal window and interacting with ipdb.
PyCharm has a feature called Intention Actions that provide automated solutions to problems the editor detects in your code. These include using a symbol that isn’t found in the current scope, improper return values and small refactors that can make your code better, among other things.
According to the docs, there are three types of Intention Actions: “Create from usage” (missing symbols), “Quick fixes” (problems your in your code) and “Micro-refactorings” (e.g. convert lambda into function def).
When an intention action is available, you will see an indicator in either the status bar on the bottom of the window, the text itself (if it’s a syntax error or unresolved symbol) or both. Then you can use a keyboard shortcut to trigger a menu of actions available.
While you can use intention actions to create class, class method and function stubs, I don’t often do this. I do regularly use them to fix errors and add import statements.
The result is that I feel like I'm pair programming with an observant coworker who has memorized Python syntax, a small dictionary and PEP8.
Error Detection and Resolution
PyCharm detects several types of errors in your code and will offer to fix them for you through the Intention Action feature. These include the types of errors that you probably already use
pylint to check for in your editor of choice: syntax errors and PEP8 violations. It also detects spelling mistakes with what appears to be a very limited dictionary.
Beyond these simple scans, the editor understands Python in the sense that it can detect common design mistakes, like not closing a resource, and offer automated solutions. It can also detect alternative style choices, like single-versus-double quotations, and offer to change between them.
Erroneous statements are underlined with a red squiggly line by default, but this is configurable. One of the options in the Intention Action menu for an error is to silence it. You can also configure whether PyCharm should check for spelling errors in code, or in comments only (or never).
This is a great feature that I didn't record a video to show because it looks exactly the same as Intention Actions in “Code Generation.” As with that feature, it feels like working with a pedantic-yet-helpful pair programmer.
If you haven’t used refactoring tools before, this is a feature that automates the rather laborious process of doing things like renaming a method or variable that may have dozens or hundreds of usages across a project.
Doable with ack (or grep) and Vim. But would I want to go back to that life? No. Here’s why. Let’s say I want to rename a method with a name like “add” that’s guaranteed to give me false positives from a text-based search like grep. In PyCharm I trigger the refactor menu with a keyboard shortcut:
Alright, great. I have tons of refactoring options. I’m only going to show renaming because that is what I do the most. So, I hit the Enter key on “Rename…” and I’m asked for the new name:
What’s that “Preview” button? Oh, it’s just a sweet tree containing all the occurrences of the symbol.
From the preview, I can right-click on any branch of the tree and exclude all sub-items from the operation. There’s a button at the bottom (not in the screenshot) that lets me cancel or do the refactor.
If I want to undo the refactor, all of the changes are rolled up into a single undo, and I get a special dialog box (“Undo renaming method to add_please?”).
Pip and Virtualenv Integration
Virtualenv and Pip support are woven into PyCharm, and both work pretty well. When you first open a directory of Python code, the editor warns you that the project lacks a Python interpreter. At that point you can choose to use the system Python or a virtualenv Python.
If there is a
requirements.txt file in the project, PyCharm will check to see if the interpreter contains all of the referenced libraries, and if it doesn't, a warning will flash on screen that offers to download the missing packages for you.
When a project uses a non-standard requirements file name (or multiple requirements files), you can set the name of the requirements file in the Python Integrated Tools section of the settings window.
I've heard that PyCharm can detect which virtualenv to use for a project. This probably relies on you having created the virtualenv inside of the project directory structure, which I don't do. I have my virtualenvs in
~/envs and my source in
~/src, so I manually configure a Python interpreter for new projects. It's still pretty convenient.
Because PyCharm knows about Python interpreters, when you create Run actions (or run an automatically created one, e.g. for a test) you can choose which interpreter the action should use. The default is the currently configured project interpreter.
Awareness of virtualenvs is a nice background-level feature that underpins all of the rest of PyCharm's code intelligence features, which are of course amazing.
Almost every command in PyCharm has a keyboard shortcut, even some of the commands that might seem available only from the top-screen menus. Many of these are not configured out-of-the-box, so you must stumble upon them like lost treasure.
If you're just exploring for new PyCharm commands, an easier way to find them is to use the Find Action command (Shift+Command+A on OS X). This opens up a searchable menu of commands alongside of which is the currently-mapped keyboard shortcut. This is probably one of the most important features for new users to PyCharm. I encourage you to spend some quality time with it!
You configure keyboard shortcuts in the Keymap section of the settings window. The Keymap section has a textbox that you use to filter all the available commands. The filter helps if you have a vague idea of what you want to do, like "window" or "project," but in my experience you often need to do some internet research to find new commands. Changes you've made from a default keymap are highlighted in blue when you return to the Keymap section.
Once you find a command you want to map or remap, you double-click on it to bring up a context menu. The menu lets you remove a keybinding or add a new one. You can add multiple shortcuts to a single action (not sure why) and multiple commands can have the same shortcut (very useful because not all commands are available all the time). If your chosen shortcut is already in use, the editor will warn you and give a list of all the commands that overlap.
Tab, Split and Window Management
When it comes to splitting the editor into multiple panes, there’s good news and there’s bad news.
The good news is that PyCharm supports arbitrary window splits in a way that's more intuitive than Sublime Text and somewhat less than Vim. Typically you’ll have each project open in a separate window, but you can also yank a tab into its own window or detach one of the many different tool panels into a separate window.
PyCharm represents an open file with a tab. I don't use tabs with Vim, so at first it seemed like JetBrains had dumped something foul in my cereal. Tabs have grown on me since then, in large part because the tools the editor includes for jumping between open and recent files mean I don't pay much attention to tabs except when I really need to.
You can configure the editor to either keep adding new rows of tabs as your number of open files fills the current window, or to hide tabs that don't fit. If you let it hide tabs, a small button appears in the upper-right corner of a window when some tabs are hidden. You can click on the button to see a list of hidden tabs. When you use a hidden file, its tab comes out of hiding and an older tabs is hidden in its place.
If you desire ruthless efficiency, you can set a “tab limit” that defaults to ten. If you open more than that number of tabs, PyCharm start closing old ones. You have a couple of options for the tab-closing strategy.
The bad news is that window splits are not quite the smooth-as-butter experience that you get with Vim. The biggest problem I have is with how PyCharm handles opening a file by name (through the Navigate to File command) from a split when the file is already "open" in another split.
If you do this, your cursor will jump to whatever split the file is already open in. Vim would open the file in the current split, which is the behavior I’ve come to expect. I get why they did it, but I'd prefer this to be a configuration option.
As for windows, PyCharm is a modern OS X application, unlike Vim and even MacVim, so you can have files from multiple projects open in multiple windows galore and it properly tracks the project context for each window.
Jumping to Open and Recent Files
In Vim and Emacs I used plugins like bufexplorer and ibuffer (respectively) to get an overview of open files and to quickly switch back and forth between them.
PyCharm has a couple of features like this. First is the list of recent files, which you can trigger with a keyboard shortcut. This list is searchable and defaults to the last file you had open. If you start typing, it filters down the list of items.
This is great because I don’t even keep track mentally of files I may have opened 16 files ago — I get a helpful list that jogs my memory ("What was that one module I was looking at with the broken thing…?").
You can also hone this down further with the Recently Edited Files command. This is just the subset of files you've edited in the past N minutes (I don't know how long).
Finally there's the Switcher command. This is similar to the Recent Files list except it operates on your open tabs. By default the keyboard shortcut on OS X is Control+Tab.
I don’t even notice these features anymore because they’re muscle memory. Most of the time I’m using them to jump back and forth between a few open files I’m working on — or more often, the immediate last file.
Jumping to Files on Disk
Get ready because these features pack heat. Well, at least one of them does (the navigation bar — keep reading).
PyCharm lets you jump to any file in the current project using a fuzzy search against the file name and path, like Sublime Text, Eclipse, Xcode and Vim with certain plugins. It works very well. The UI is similar to “Goto Symbol,” a list of partial matches that filters down as you modify your search text. I use this all day, when I’m not using the Recent Files menu to open files. One really nice thing about it is that with a small tap of a key in the result window you can see "non-project" items too — these are search results across the entire Python environment, including all of the project libraries. Very useful.
In PyCharm 3.1 there is also a new Search Anywhere command that combines searching for project symbols and filenames. I haven't fully transitioned to using this instead of the separate navigation commands, but it seems useful.
If you like to see a tree of files, though, PyCharm has a comprehensive one that
works better than Sublime Text's and NERDTree in Vim. You can easily show and hide the tree with a keyboard shortcut. When the tree is focused, typing filters the visible files. The UX on the filter is nicely done — matching item are highlighted, and only these are available when you use the up and down arrows. This is probably easier to understand in the video demo.
Other than that, it probably looks like any old file tree, but its context menu is powerful! I don't know the keyboard shortcut to open the context menu, but you can see it by right clicking on a file (as usual).
Honestly though, I don't use the tree often because there is something way better called the navigation bar. I’m not sure how to describe it other than that it’s like a keyboard-navigable breadcrumb file tree. I’ll have to show you. Here is what it looks like in its default position (I usually have it hidden by default):
“Ugh, so crowded!” you probably thought. Yeah, I know, that’s why I have it turned off. But check this out — you can still activate a special floating version of the navigation bar with a keyboard shortcut. I have this command mapped to Command+Up-Arrow and use it all the time. Watch a video that shows how smooth it is.
As you can see in the video, the Navigation Bar allows you to open a Refactor command on files in the directory tree, which includes the ability to rename, copy and delete them easily without losing your focus. I'm going to be at PyCon Montreal this year, where I'll buy a beer for whoever made this.
A seemingly insignificant feature — automated reformatting of selected code to configurable spacing and indentation rules — turns out to be another one I use all day. Here’s an example of me correcting spaces and indentation on a block of Cornice code — first I select the problematic lines:
Then I use my Reformat Code keyboard shortcut to fix the indentation:
Each language has its own configuration section for this feature. Here’s a screenshot of Python’s:
Most of the time, this feels like an unconscious extension of my will. It also helps me to ensure that my code is following a project's style guide.
Props aside, Reformat Code doesn’t always understand how I want the reformat to happen because there are ambiguities — for instance, it won’t add a line break for each parameter in a method call to make it a bit more readable when that seems like the best thing to do.
Then there are just plain old errors, like the fact that it won’t reformat docstrings or comments to my configured column width (I had to write my own plugin to do that). Or that it occasionally it moves lines to the wrong indent level.
Still, I’ll often sweep whole function definitions with with Reformat Code as I’m writing, to clean up after myself, and then fix the one or two things PyCharm didn’t do quite to my liking.
PyCharm 3 offers a built-in terminal emulator. It's a decent terminal that I can keyboard-shortcut into to run a Django management command or see a Git diff. However, there are other tools in the editor to do both of those things that are a little nicer — a Git diff viewer that surpasses the command-line output from Git, and the Run Action system that allows you to create reusable actions for running Django management commands.
That said, despite nice Git and GitHub tools, I still use the command line for most of my Git work. However, I use iTerm for this because PyCharm's terminal doesn't seem to work well with tmux, and I can't live without tmux. I think this is a natural problem of hosting a terminal emulator within a text editor powered by keyboard shortcuts — PyCharm appears to swallow my tmux command prefix (Control+A). However, if you don't use tmux (and maybe if you don't use screen either), or don't need to use them from within PyCharm, it's a decent terminal.
Coming from Vim and Emacs, I’m somewhat dissatisfied with color scheme support in PyCharm. There aren’t many color schemes bundled with the editor, and the selection among community-created color schemes is thin in comparison with Vim’s.
I’ve also had trouble with a color scheme either lacking the option to change the color of some syntax, or using a color for a piece of syntax without giving me the option to change it (I lack a good example of that, but I remember it happened with CoffeeScript).
Still, there are upsides. There’s a nice graphical configuration panel that lets you override colors for different languages, and support for importing custom color schemes.
Here’s a screenshot of me editing colors for the Solarized Dark scheme and Python:
There is also a new feature called “Look and Feel” that affects your experience with the editor. The Look and Feel choice is a theme for the PyCharm UI chrome, like the tabs, gutter and status bar, which by default are all a metallic gray color.
In my screenshots I’m using the “Darcula” Look and Feel setting, but here’s a screenshot of me using Solarized Light and the default UI Look and Feel:
All in all, color scheme support is decent. I'm not entirely satisfied because there are too few color schemes packages with the editor and too few available from the community. There is also not an easy way to discover new, non-bundled color schemes from within PyCharm, which would be nice.
Editing, Backing Up and Restoring Configuration
Project and IDE settings are configured using a graphical interface that is searchable. I’m not sure I prefer it over a text file, but then again, I don’t get syntax errors changing configuration anymore.
I've shown the settings window in video demos elsewhere in this review, but in case you missed it, here is a screenshot:
What I do miss is having a single source of configuration “truth” for my editor — like a
.vimrc file — that I can place in version control and share among computers. With PyCharm, you can export and import your settings, but the resulting file isn’t exactly human-readable. Oh well.
If snippets are your thing, then you can find lots of videos of people using PyCharm templates to nice effect. I don't use them very much.
Running Arbitrary Code
Ok, hold onto your pants — there is no built-in support for creating scratch files.
You read that right. I know, I know, that has to be a terrible lie, right? Well, it’s the truth. To write code in PyCharm you must create a named file that becomes associated with the project. BUT WAIT, THERE’S A PLUGIN.
Fortunately for my sanity, the Scratch plugin adds some nice keyboard shortcuts (and menus) for creating arbitrary files of any type the editor supports, which result in you getting completion and all the other fancy features, as long as you’re referencing symbols that exist in the current project.
Opening PyCharm from the Command Line
The editor will create a charm binary that you can use to open files in PyCharm from the command line. It works pretty much the same way as using
vim <filename>. The only downside is that files open in your current project. That’s not always what you want, and I’m not sure if there’s a way to tell charm to launch them in a new project or in a specific project.
Compared to Vim, there aren’t many available plugins. This hasn’t been a problem for me because 90% of the features I used plugins for in Vim are either built into the editor or available as a plugin. There may not be a plugin to post to Orkut for you, though. You’ll have to get down in the mud and cut some Java for that one.
The plugins that are available are all discoverable through a configuration panel from within the editor, which is great. They’re searchable and include details about the current plugin version and author.
Here’s the configuration panel that shows your currently installed plugins:
And here’s the panel that opens when you want to search for plugins in the plugin repository:
If you use Sublime Text or Emacs, you already have a tool like this, so it will be familiar and perhaps a little troubling, since occasionally you might have to click a mouse button.
Coming from Vim, this was a great feature. I’ve used several plugin management plugins for Vim and they were decent, but usually lacked a good discovery mechanism.
Unlike Sublime Text or Vim, you have to use an entirely separate editor to edit plugins — Intellij IDEA Community Edition. The good news is that it’s free.
The bad news? You have to write plugins in Java.
I’m going to save additional details about writing plugins for a potential future blog post, after I write a couple more Intellij plugins to get experience. However, in summary I’ll say that I didn’t mind writing Java but I had a hell of a time finding comprehensive documentation on the plugin APIs.