Our Day-to-Day Guide to Productivity for Android developers — Part 2
By Christian Kula (Android developer)
For this second part of our series of Our Day-to-Day Guide to Productivity for Android developers, let’s talk about Code Editor and Git tips and tricks.
You may know some, you may not know others. In any case, feel free to share them!
Android Studio
Since we use Android Studio everyday, it’s very important to know how to use our tools in order to perform better. Also, since Android Studio is powered by the IntelliJ platform, most of these tricks can be used in other IntelliJ-based IDEs!
Editor
The IntelliJ editor is very powerful. Besides basic “Find & Replace” or move lines around, it can do so much more ! And since it’s language-aware, it won’t mess up your code (too much at least). Each section title refers to the name of the command in Android Studio so you can easily find it by name if needed.
Move line up/down
Option + Shift + Up/Down (macOS)
Alt + Shift + Up/Down (Windows/Linux)
Let’s start with an easy one, you just want to move a line up or down. No need to recopy or cut & paste the whole line, use the keybinding to move the line the caret is currently at up or down. Easy!
Move statement up/down
Cmd + Shift + Up/Down (macOS)
Ctrl + Shift + Up/Down (Windows/Linux)
Now, let’s say you wrote an awesome class and you want to move whole blocks of code to be logically located inside your class. You could cut & paste your method block. Or, you could simply move your caret to the method’s signature and press the keybinding. The whole method block will be moved up or down, with respect to code syntax. Like the name implies, you can move statements so it includes methods, variable declarations, expressions, whole classes etc.
Use “CamelHumps” words
Option location:
Preferences > Editor > General > Smart Keys > Use ‘CamelHumps’ words
With this option enabled, every selection or navigation inside a camelCase word will honor the “hump”. In other words, in a word like AppCompatActivity, App, Compat and Activity each represents a Camel hump and the editor will treat them as a word even though there’s no space separating them. You may not see the usage but wait for the next trick below!
You can also enable “Honor ‘CamelHumps’ words settings when selecting on double click” if you use the mouse.
Preferences > Editor > General > Honor ‘CamelHumps’ words settings when selecting on double click
Extend/Shrink selection
Option + Up/Down(macOS)
Alt + Up/Down (Windows/Linux)
This feature is also very useful for quickly selecting chunks of code! The “Extend selection” command allows you to successively select expanding logical blocks of code so that you can easily select any expression in the code by placing the caret somewhere inside it and pressing the shortcut a few times. And “Shrink selection” is the opposite. And it also works nicely with CamelHump words!
Rename… (and its spiritual brother “Add Selection for Next Occurence”)
Rename…
Shift + F6 (macOS, Windows & Linux)
Add Selection for Next Occurence / Unselect Occurrence
Control + G / Ctrl + Shift + G (macOS)
Alt + J / Alt + Shift + J (Windows/Linux)
Please, if you need to rename a class/method/variable/parameter, don’t rename it manually as you’ll likely forget to rename one instance somewhere in your app, thus leading to compilation errors.
Use the “Rename…” function, it’s super smart because it can rename every reference to the changed name (even in Java/KDoc and in String values!) and it’s scope-aware.
Be careful, though. Sometimes it may go too far and AS will want to rename unwanted String values in strings.xml files. Fortunately, AS will prompt you to confirm the change if it’s not trivial and you can omit specific references from the rename process.
“Add Selection for Next Occurence” serves a similar function but its use case is a bit different. When you press on Control + G, AS will select the current word (remember “CamelHump” word). If you press it again, it will select the next occurence of the selection in the current file. And so on. And now, you have duplicated carets at each selection place so you can edit all occurrences at once. It’s a kinda fancier and more flexible “Find & Replace”.
Navigation
Android Studio has a lot of very convenient features to navigate to and in files and classes etc.
You probably know “Press Shift twice to search everywhere” but it’s most likely overkill. Most of the time, you want to find something specific like a class or file. There’s no need to make Android Studio search in E V E R Y T H I N G (classes, files, symbols, actions, settings etc.) if you’re looking only for a class.
Make your searches faster by using the corresponding optimized “Find …” feature and use “Search everywhere” only if you don’t know exactly what you’re looking for.
Find a class (or an interface)
Cmd + O (macOS)
Ctrl + N (Windows/Linux)
When you’re looking for a class or an interface with a specific name
Find a file
Cmd + Shift + O (macOS)
Ctrl + Shift + N (Windows/Linux)
When you’re looking for a file with a specific name
Find an action
Cmd + Shift + A (macOS)
Ctrl + Shift + A (Windows/Linux)
If you have to remember only one thing from this article, remember this shortcut because it is the MOST USEFUL one. I kid you not, this feature is super convenient to the point I wish more text editors would have it.
It’s simple : it will search for an action you can do in AS. Any action. Literally.
You don’t remember the shortcut of “Rename…”, where the option to turn on Presentation Mode is or you need to quickly change your editor theme to Darcula because your coworker can’t stand the Light theme? Press Cmd + Shift + A, type a few letters and ta-da, AS will show the matching actions.
Basically, you have access to EVERY feature of AS a few keystrokes away.
Find in path
Cmd + Shift + F (macOS)
Ctrl + Shift + F (Windows/Linux)
Another useful search option. Let’s say you know that a file contains some string of characters but you can’t remember its filename, nor its location. By using “Find in path”, you can search for any string of characters that appear in a file. You can also specify if you want to search the whole words, match the case or filter by file mask. You can search in project, module, directory or even scope.
Recent Files and Recent Locations
Another feature that I use all the time!
Recent Files
Cmd + E (macOS)
Ctrl + E (Windows/Linux)
Recent Locations
Cmd + Shift + E (macOS)
Ctrl + Shift + E (Windows/Linux)
Like the name implies, it shows the files you’ve recently opened. Useful if you need to go back to file you’ve previously closed but can’t find anymore.
And “Recent Locations” works the same but with your cursor locations. It shows where exactly you’ve recently put your cursor.
Git
We use Git as our VCS so it’s very important for us to master it. Using GUI tools is fine but the CLI is where you’ll see the true power of Git.
AS has very good tools to compare commits and check the commit history so I use them but for every other command, I use the CLI.
reflog, your safety net
Manipulating Git repositories from the CLI can be scary, especially when using not-well known commands.
First, remember that no commit is lost in your local Git repo. Your local Git repo will still keep all your commits info even though it seems you lose access to it (via hard resetting, checking out something else etc.). You can recover from almost every situation using the commit unique identifier : its SHA-1.
However, how can you retrieve a commit SHA-1 if you happen to have lost it somehow?
Enter the reflog command.
This command will show every action that recently happened in your local repo : branch switching, merges, commits, rebases, tags etc. See it as a powerful “Repository History” feature.
Each line will represent an action in the repo with its corresponding SHA-1 so now, you have everything you need to recover from a wrong command.
Let me show you an example. Let’s say you committed something very cool but then decided to remove it and actually, you need this very cool something back.
$ git commit -m “Commit something very cool”$ git reset — hard HEAD¹// remove last commit on branch// but now you need the “Commit something very cool” commit back, how to do it ?
Using git reflog will give you something like this :
Let’s explain each line from bottom to top:
- Created “Initial commit” commit — SHA-1 : b5ec77a
- Created “Commit something very cool” commit — SHA-1 : 1e6d263
- Moved back the HEAD to the previous commit — SHA-1 : b5ec77a
Note that the last action SHA-1 is the same as the one of the initial commit. That’s because we moved back to the previous commit ie. the “Initial commit”.
Also, note the second line : it shows a commit with the message “Commit something very cool” was created along with its SHA-1 : 1e6d263.
Great! Now you can recover the removed commit using the cherry-pick command
(cherry-pick applies a commit using its SHA-1 to the current branch.)
$ git cherry-pick 1e6d263
Result
We got our previous commit back!
Note: a new SHA-1 has been generated for the cherry-picked commit
This is a very simple use case of reflog but it can show you much more very valuable information so don’t be afraid to play around in your Git repositories.
Remember, reflog is your safety net.
Example of what’s regularly happening on my branches (checkouts, rebases, resets etc.)
Also, don’t forget to COMMIT OFTEN. Committing your work is like saving a file : do it often to not lose your progress (and otherwise, reflog won’t be able to help you!)
More information: https://git-scm.com/docs/git-reflog
rerere
Behind this strange name hides a very useful feature. rerere stands for “REuse REcorded REsolution”.
As its name implies, when this feature is enabled, any conflict resolutions, when merging/rebasing, will be recorded by Git. Later, if you happen to stumble upon the same conflict again (for example, you rebase multiple branches and every rebase triggers the same conflicts), Git will REuse the previously REcorded conflicts REsolution and won’t prompt you to resolve it yourself again. Quite handy, right?
To enable rerere functionality, you simply have to run this config setting:
$ git config — global rerere.enabled true // to enable it globally for all your Git repos on your machine
OR
$ git config rerere.enabled true // to enable it only in the current Git repo
If Git can’t resolve a conflict itself, it will let you do it as usual.