Efficient development — Avoiding the chores of programming

Tsvetan Dimitrov
paysafe-bulgaria
Published in
16 min readJan 25, 2023
Programming chores are just like the ones in life, once you get used to solving them you don’t even notice doing it

What are “chores” in programming?

When you look up the definition for a “chore” you can see it classified as

a routine task, a tedious but necessary task

In life that would be doing the laundry or throwing the trash. In programming it would be building your app before you run it or setting up an environment. Doing these kinds of things is never fun or painless. You could be doing anything but you’re stuck in this tedious process until you finish it because it has to be done.

As programmers we have the ability to rise above those chores though. But we rarely do. You’d be surprised at how many people still keep doing the same command sequence over and over and they refuse to automate it because they “can’t find the time”. You won’t find the time on the street though, in life, and especially in a professional setting, time is often made, it’s not found.

There is however an overlooked subset of chores that we frequently avoid improving simply because they seem too small to have any room for improvement. I’d like to zoom in on these so called “micro chores” and show you a few tips and tricks to get better and faster at dealing with them. The term micro chore is something I thought best describes these really tiny tasks that we face every day. A micro chore is something so small that you’d think it has a negligible impact but will in fact build up over time to end up as a mountain of wasted time.

In real life a micro chore is something like cutting your apple before you eat it. It makes it easier to eat and saves you a mess but that requires you to spend some time to de-core and slice the apple. However, it would be faster with one of these:

Using a specialized tool to slice an apple

You’ve just solved a micro chore. You can now slice apples many times faster and all it took was a specialized tool.

In general that’s what we humans do when we need to automate or improve some tedious process — we create specialized tools. That’s the same approach we use in programming. In programming micro chores are things like preparing a query or test data, refactoring parts of the code, navigating a project structure, etc. Lots of small things that build up with time. In the next few paragraphs I’m going to show you how to considerably increase the speed at which you perform these tasks.

Boosting your coding speed by eliminating micro chores

An important asset for increasing coding speed are shortcuts. Don’t be intimidated by the sheer amount of shortcuts you have at your disposal though. The way to learn those is slow and steady as you incorporate them in your daily coding little by little.

A very cool thing about them is that they are usually grouped by operation. For an example when you add/remove the modifier keys Ctrl and Shift to a combination something changes on a different dimension. Use Home and most editors will send you to the beginning of the current line. Combine that with Ctrl to get Ctrl+Home and you’re getting to the beginning of the file. Combine that with a Shift to get Ctrl+Shift+Home and you will not only go to the beginning of the file but you will also select everything between the current position of the cursor and the beginning. Pretty neat, huh?

For the example parts of the article I will be using IntelliJ as an example, but don’t let that discourage you! Most of the techniques below are perfectly capable with just about any modern browser. As long as it’s regularly updated with new features and has widespread support, you can probably find your IDEs equivalent with a simple Google search.

Navigation

This is probably the most commonly done micro chore we do as programmers daily. The thing that all of us do most when writing code in a project is navigate it. I often catch people using the mouse when navigating through an editor and that’s perfectly fine but most of the time there’s a shortcut that will save you the trip to the mouse and will often be much more effective. IntelliJ has a convenient menu item called Navigation that houses all those neat navigations.

Navigation menu in IntelliJ

That’s just another way to use your mouse though. Most of the actions there have shortcuts assigned by default. I’m going to go over the navigations that I most often use during the day and share the shortcuts that I use them through. Navigation can be separated in a few categories depending on the context. Here’s what we have going from more global to more localized contexts:

  • Project navigation — the context is the whole project opened in the editor
  • Intra-file navigation — the context is the currently opened file
  • Function/method navigation — the context being the method/function
  • Line navigation — the context is the current line. Yes, we can actually go this low (and even lower but that’s just nitpicking).

Project navigation

Navigating your project is something that you do very often. Most applications nowadays have numerous modules/packages and getting through those efficiently is imperative to developing fast. Project navigation is pretty much the same no matter what programming language you’re using. The most important and commonly used actions are the following:

Navigate to class/file

Going to a class or file is important because when you’re familiar with a project you know where the functionalities you need are and going to that specific class can be a hassle if you don’t use the shortcuts. For an example using the Project View is a pretty inefficient approach. Not only do you have to traverse the folders, you’d also need to know them by heart which is rarely the case. Learning the file names though comes pretty easily, especially if you’re the one that came up with them or if you use them often enough.

IntelliJ provides several ways to do this. You could go to class(Ctrl+N) or go to file(Ctrl+Shift+N). The difference being that one file could have more than one class of course and sometimes you can’t exactly remember one or the other. You could also use the go to symbol(Ctrl+Alt+Shift+N) but it has the same problem as knowing the full project tree — you have to remember the name of the symbol for it to be useful which is rarely the case.

Go to class with IntelliJ

Navigate back/forward

Another useful feature is the go back and go forward functionality that IntelliJ provides. It’s pretty much the same as what you have in browsers that enable you to go back and forth between pages. I’ve used this in VScode as well and almost every editor I’ve tried. You use Ctrl+Alt+Left Arrow and Ctrl+Alt+Right Arrow to use it.

Navigate back/forward with IntelliJ

Navigate to declaration/implementation/type…

Navigating to the building blocks of your language is a great feature that the more specialized editors provide. IntelliJ is pretty great in that respect as it allows many such navigations. The most common denominator of these is that the “easy” shortcut is always hover with the mouse and hold Ctrl and left click. That usually does the trick to get you to declaration, implementations are a bit trickier of course. Personally I’ve learned the following:

  • Go to declaration — I use that pretty often to go to a class field and look at the context or change something in/around it. If it’s a method/class I’m targeting I can also check the context and what the API has to offer. Ctrl+B should be the default for IntelliJ.
  • Go to implementation — this one’s really useful when you need to check out the inner workings of some class/method while reading code. Invaluable when reading more abstract code as the navigation to the declaration wouldn’t do you much good if you want to see implementation specifics, which is almost always the case when you’re going over some flow. Ctrl+Alt+B should be the default for IntelliJ.
  • Go to type declaration — this one’s a bit more peculiar than the others but it’s been such a great help over the years that I had to include it here. It allows you to go to the type of the variable that you’re currently hovering. Ctrl+Shift+B should be the default for IntelliJ.
Go to type definition in IntelliJ

Intra-file navigation

Navigation inside the files is another thing that we do a lot every day. Efficient file navigation makes sure you spend less time moving around and more time thinking or writing code. There are a few key positions that I’ve noticed that I often navigate to.

Previous/Next method

This one’s really good when you need to go up to maybe change a parameter. Note that using this for checking out the signature is a bit wasteful, you’d be better off using Alt+Q which “peeks” at the method signature

Go to Prev/Next method in IntelliJ

Next error/warning

Another very useful feature I use daily is going to the next error/warning in a file. When I change something and take a look at the breadcrumb on the side and notice an unforeseen error from my change I want to go directly to it so that I can see it in context. Now you could just scroll there or click the breadcrumb but that would require you to switch from keyboard to mouse again and spend some time searching. IntelliJ has this hotkey on F2 by default.

Go to next error in IntelliJ

Go to the beginning/end of file

I sometimes need to do this when I need to look at the class/file comment for an example or if I need to reposition and walk over the methods from top to bottom or the other way around. Usually good practices would have your code be sorted in a particular way — public first, private last or something similar depending on the type of your project and your language of use. Going to one of the extremes would let you to quickly and efficiently walk over the code scanning for inconsistencies or some spot in the code that you know by general position.

The shortcut for this has been the same on pretty much every editor I’ve tried sans the really odd ones and it’s always been Ctrl+Home/Ctrl+End respectively for beginning/end of the file.

Function/method navigation

Function navigation can also be broken down into some smaller chunks. You can of course use the above file-oriented navigations to navigate throughout the method but there are some more localized ones that would help you cruise through the method as if it’s its own isolated block of code.

Opening/Closing curly brace

I often use this to traverse the beginning and ends of code blocks like methods, classes, static blocks, etc. It’s most useful to me for function navigation as it allows me to easily scan the beginning and the end of the method for specific markers like parameter count and names, although a “peek declaration” operation would be better suited for that purpose. “Move Caret to Code Block Start/End” is the name in IntelliJ and is usually set to Ctrl + [ and Ctrl + ] for open and closing curly brace respectively

Go to curly brace in IntelliJ

Opening/Closing bracket

I do this often when I have some pretty big multi-lined and multi-bracketed statements. Those are pretty rare and are a code smell but it happens. Also I guess lisp programmers would like that one. I’ve had to manually set my shortcut for this in IntelliJ so just look up “Move Caret to Matching Brace”

Go to bracket in IntelliJ

Peeking

This one is more of an annotation functionality but it still lets you pseudo-navigate to the beginning of the method/function. Using this would allow you to peek at the definition/comment of a particular object. The most useful ones I’ve used are the Context Info(Alt+Q in IntelliJ) and the Quick documentation(Ctrl+Q in IntelliJ) annotations. I most commonly use the context info to check the current method’s signature and above. If you press more than once you get one level above, for an example — current method signature comes first and then the enclosing object and so on.

Context info in IntelliJ

The quick documentation one is useful when you don’t want to open a type and pore through the documentation manually. It will open a floating popup that won’t interrupt your flow or make you have to close your current file in order to read it.

Quick documentation in IntelliJ

Line navigation

Line navigation is a pretty low grained task but it is surprisingly multifaceted. You have a bunch of things you can traverse inside a line: characters, words, symbols, etc. The most commonly used shortcuts when navigating a line are combination of the arrow keys with some modulating keys like Ctrl and Shift. Here’s the ones I think are the most useful:

Jumping over words

This enables you to skip a word when traversing a line. The words are usually different symbols in the code — variables, classes, types, etc. This allows for a speedy navigation to a specific point in the line instead of having to use the mouse. It’s important to note that sometimes the line is so irregularly typed that you might as well use your mouse. Most times though the keyboard combined with the Ctrl modifier allows better or similar performance. Jumping over words for an example is done with Ctrl+Left/Right

Jumping over words in IntelliJ

Note: combining this with a Shift and turning it into Ctrl+Shift+Left/Right will result in the skipped over character to become selected as well (just like they would if you didn’t hold the Ctrl at all, but batched by word).

Going to beginning/end of line

The beginning and the end of a line are important markers in most languages. That’s where names, semicolons, brackets and other important building blocks reside. Getting there fast is always helpful. If you remember the Ctrl+Home/End combination from the section on file navigation you wouldn’t be surprised that if you exclude the modifier Ctrl key you’d go to the beginning/end of the current line.

Carets

A simple but incredibly powerful feature of pretty much every modern editor are carets or also called multiple cursors. They enable you to have multiple cursors(duh) active at once therefore modifying a few lines at once. Really efficient for data modification. The best part about it? You can use most of the above tips I explained about line navigation and do them for multiple lines at the same time. This results in a powerful tool for data modification as you can see in the example below.

Carets example in Sublime Text 3

I’m using sublime here just to showcase how even with a simple IDE you can have a whole bunch of powerful plugins and functionalities like the “Increment selection” plugin and the prepackaged lower case commands that exist in pretty much every modern browser.

Regex and multi selections using it

Many modern IDEs give you the ability to find and select multiple found matches that generates the carets I showed you above. That helps when your data is not neatly ordered one per line with every piece starting at the start of the line. You can use the find functionality for those cases. And the best way to do it is to combine it with Regex as well as it’s incredibly powerful for finding similar blocks of text. Check out the below example to see how much easier using regex was.

Regex search and extract example in Sublime Text 3

In this example I extracted all the JSON fields that have a “name” inside of them. For that purpose I used the +”\w*?name\w*?” regex string. It found all fields that contain “name” in their key. I then used the Alt+Enter combination in Sublime to select all results in the search and then the Shift+End combination to move the currently selected carets to the end of their line which resulted in me getting a whole selected line. Then I moved the selected data to a new tab for better viewing which enables you to analyze the specified names.

I could have used some overly complex combination of the other techniques I showed you but it’s much simpler with regex once you learn the most basic of its syntax. The above might look like an overwhelming string of gibberish but it’s really not as hard as it looks. I’m not going to go into the specifics, you can check out any number of great regex guides out there to show you the ropes but I just wanted to show you one application here. Another good application is validations and data modification with the Find and Replace function so there’s a lot of overlap with the usual developer tasks.

Complex chores

The complex chores are probably what you expected to see most in this article, which is why I’d rather keep this part more theoretical, than show you examples that you’ve probably already seen. Complex tasks include the introduction of things like build scripts, data transformation/manipulation scripts and test environment setup scripts. Yep, all those things you avoid creating for your local environment. Another motivation of this part of the article is to give you a reason to want to create those scripts you’ve been putting off.

Why should I write build/env setup automation scripts?

I prefer moving most of the build sequences I do locally to scripts for several important reasons.

Automation

The main reason. It just saves so much time. Having to run the builds manually, then deploying them on your local server, maybe busting a few caches, whoops you forgot the in-memory database config, gotta go back and start over. You probably get where I’m going and some of you’ve probably been there before and have hopefully rectified their mistakes. Automating the boring, menial tasks is something that every developer should be able to do effortlessly. It’s what keeps our jobs from becoming too mundane and making us burn ourselves out.

Documentation

If a picture’s worth a thousand words, then an environment setup script is worth a few pages of documentation.

There’s this concept called “self-documenting code”. It’s a really great idea that basically states that if your code is written simple enough, you wouldn’t need to document most of it but only the important or necessarily quirky(e.g. external dependency constraints) parts of it. A build/environment setup script doesn’t just automate your job but it also serves as a documentation on what building parts you need for the application to run. Avoiding all the hassle to sometimes re-learn what it was required for a project to run locally is a great side effect from having those scripts.

We all know all the different environments (integration/stage/prod…etc) are almost always very different than our local ones. Whether it’s resources, mocking or timing constraints it’s just not efficient to run a project locally the same way you’d run it on other environments. Because of this though the scripts on the agents are different than what the ones on our local machines have to look like and that’s why a lot of people just don’t do it. They set them up once and forget them resulting in a huge hassle to relearn everything when they have to change something or something just breaks out of nowhere. All those flying environment variables and compile arguments spread around tons of files and configurations. A thoroughly unpleasant task that could be saved by spending an hour or two extra setting stuff up.

Transferability

Being able to share your script with a colleague will more than double the time saved to set up a new project locally. Sharing with another one would increase that even further. With the added bonuses I mentioned above comes the easier to understand steps that can save you some onboarding time for new people.

Language choice considerations

I don’t want to go and explore a bunch of language specifics and introduce pointless noise so here’s some things to consider when choosing your language.

The scripting language for your scripts greatly depends on what you’re trying to achieve and the project you’re dealing with. If the build steps include a lot of OS specific stuff like file movement and maybe some environment variables set up then you’d probably be better off using what’s best suited for your OS. The shells are usually a great choice as an all around solution. zsh, bash, just sh or something a bit more exotic like fish, depending on your system, needs and preferences, are often a great and minimal way to set up an environment.

Some famous shells, from left to right — bash, fish, zsh

If you’d rather do more complex tasks you might want to choose a different language that is easier to write than the shell ones. The syntax there is clunky and not at all user friendly so something like python would make your life considerably easier when writing more logic intensive scripts.

Python is great at more application logic intensive scripts and has a friendly syntax

Aliases

Build scripts usually include build tools and their respective configurations like for an example java most of the time makes use of Gradle or Maven. Sometimes Ant makes an appearance. They also have a lot of file movement but that’s mostly wrapped by the build tools. If you want to setup a project locally chances are you already have it chosen for you. There’s a trick to improving your experience with them though and that is through using aliases.

Aliases are a great way to add an extra layer of automation to some short commands that you do often during development. Using the build scripts and the tools as an example — sometimes you want to run the build tool with different inputs depending on the type of build you want to achieve. If you’re going for speed and want a running project ASAP you’d want to skip all documentation generation, tests, test compilation, etc. Anything that is not important to get the project running. If you’re pushing to the remote though you probably want most of those skipped tasks to be enabled. Aliases are a shell concept that allow you to turn a command like ./gradlew clean build -x test into something like gradle-no-tests.

Conclusion

I’ll be stopping here as we could go for hundreds of pages describing efficient practices and we’d still have not covered even a fraction of what we’ve learned as developers over the short span that our profession has existed. I hope this article serves as a different perspective and makes you consider some of the stuff on the smaller spectrum that you’ve never considered could be done better. Or that it sparked you into action and finally writing that one script you’ve been putting off forever.

--

--