Ask HN: What are your favorite developer-efficiency tips?

566 points by kanyethegreat ↗ HN
I recently started integrating tmux and vim into my workflows. Obviously, it was a huge efficiency booster. What are some other tools (custom built or off-the-shelf), hotkeys, workflows that were game-changing for you as a dev? I'm interested in hearing about anything and everything (stuff from ctrl+l to clear the terminal to little-known git commands to larger-scale strategies like CI/CD)

531 comments

[ 2.3 ms ] story [ 301 ms ] thread
C-r for interactive history search
Not just that.

Add this to you inputrc:

"\e[A": history-search-backward

"\e[B": history-search-forward

Now up and down arrows will search your history with whatever you already have typed at the prompt. Re-running a command often? Probably just have to type its first letter and hit up arrow once or twice.

I like fzf for command history search. Ctrl-r, then fuzzy search the command, arrow up and down. Nirvana
fzf is game changing. Having have to guess exactly with Ctrl-R is a thing of the past.
This is AMAZING. Thanks so much!

(fyi, for others: you need not use ctrl-r, just type and press up and down)

fzf, ripgrep, fd, tree, fish shell with z plugin.
Learning basic *nix commands like sed, awk, and grep has helped me so much. I still frequently google/manpage them, but I often find myself thinking "I can do this with X in just a few seconds!"
being medium-grade conversant in regular expressions is right up there, too. You might not need to do lookaheads, but if you can write a regex search in vscode that finds and replaces something across a hundred files correctly, you've just saved yourself a ton of tedious manual labor.
password manager
Which one do people here recommend?
Been using Bitwarden Premium (which is really cheap anyway) for a couple of years, can't say anything bad about it.
+1 for Bitwarden, it's been my recommendation for a while now.
1Password
I have been using LastPass (free) for several years, any reason I should consider switching to 1Password?
I use keepassxc. Has nice native desktop and Android apps. Also a Firefox browser extension available, though I have not tried it.
+1 for KeePass. Native apps have been great on all platforms (I recommend Strongbox on iOS).
TextExpander. You can take your most common code snippets, table names, etc., and have shortcuts that expand to the full length. I used shortcut expansion around 10-20 times every day, which saves me about a couple hours per month (based on their internal analytics report).
RTFM (as in Read The Fine Manual).

To me, the key for being productivity is understand throughly the "tools" we use: IDE, languages, libraries, framework cli, os, shell,... Read the implementation, the docs, the issue tracker, even the git history if you have time.

When I started to learn vim, I tried many popular distribution without understand each of the plugins they included. And I almost gave up learning vim. It's until I start to read the vim manual, learn the key strokes one by one and then building my own distribution, that's when I really know how to use vim. Even so, I still learn many great things from books like Practical Vim by Drew Neil (on Tmux, there's Tmux 2: Productive Mouse-Free Development)

I think you might already know that, but still shooting here for some quick tips. I don't have any shortcut, just that motto.

Love this! I found that the more experienced I became as a dev, the more I gravitated toward the less-removed sources of truth (eg. man pages instead of stack overflow, source code instead of blog articles, etc). Haven't started reading issue trackers, but huge fan of traversing a git history (assuming it's clean and atomic).
> I still learn many great things from books like Practical Vim by Drew Neil

You should also check out "Modern Vim: Craft Your Development Environment with Vim 8 and Neovim" from the same author.

Only work on one task at a time.

Do small tasks immediately - reply to that email, merge from master, do that CR, etc. Delaying small tasks tends to abandon them.

Keep your workspace clean (physical & virtual).

Update docs as you use them.

Say "No" often.

Learning to write (simple) regular expressions will allow you to find and replace in text files fluently (capture groups are especially useful). It's a lot simpler than it looks initially.
Asking lots of questions and thinking through the trade offs of more than one possible implementation before coding. Writing your implementation plan on paper especially helps find those unknown unknowns before you code. If you have trouble stating the problem and your solution in words, that indicates an unknown to investigate.

I.e. do a little writing to help avoid coding the wrong thing.

Contrarian opinion, but often doing things manually rather than automated will save you time. Writing/debugging a script is fun, but more often than not it would have been faster to do things the dumb way. If a task is risky or repetitive daily, then sure, but often developers confuse "writing a script because too lazy to manually do the work" vs "get the task done as fast as possible".
Another contrarian opinion, but as much as configuring and tweaking conf files are fun, it's still faster in the long run to be highly efficient on a new system as fast as possible. It's also convenient to use standard tools to be effective on someone's else computer. For instance, it's much better if you can be productive by changing 2-3 keys in macOS settings instead of being forced to use a fancy keyboard layout and customize shortcuts for everything.
Respectfully, I've never understood this viewpoint. If the configuration options are importable from some external repository (as the vast majority of dotfiles are), "as fast as possible" simply becomes "how quickly can I install git (or my VCS of choice) and pull down my configuration options?"

For keyboards and other physical hardware, sure, you can't remap on the fly. But I'd wager the the vast majority of productivity-customizations that people implement are software-level.

As always, it depends on what you do. On your machines, sure. On customer machines, no, quickly installing a VCS and pulling some repository is often not an option.
I truly pity the developer that has to create software (a) on customer machines and (b) without VCS and pulling repositories.
It's not just creating, but also debugging, configuring, ... I'm not even sure git runs on some of the systems I work with.

And yes, some environments take a very dim view on you pulling repositories from outside their internal systems.

I only write scripts so that I'm sure that certain repetitive tasks are done correctly - this is, for me, the value proposition of automation.
Third time you do the same thing, you should probably write some script for it.
People should realize that any kind of system or process comes at the cost of improvisation, which is always faster and lower overhead. Doing literally anything other than doing things as they come has a cost. The gamble you're making when you write documentation, automate a test, or even write code to begin with is that the investment in doing that thing will pay dividends sometime in the future.
I usually comment with the same thing on these tip threads. And that is learn to rebind your keyboard. Make each key programmable modifier. Open apps, run scripts/macros instantly. My Karabiner config:

https://github.com/nikitavoloboev/dotfiles/blob/master/karab...

I go as far as binding keys to instantly type `console.log()` or `fmt.Println()` or the other language equivalent with my dot modifier key. Plus typing things like `Thank you` with dot+spacebar press.

https://github.com/nikitavoloboev/dotfiles/blob/master/karab...

The other tip that paid off in time is starting a wiki. And building an interface to access contents of the wiki instantly.

Wiki: https://github.com/nikitavoloboev/knowledge

Interface: https://github.com/nikitavoloboev/alfred-my-mind

One thing I worry about with these extremely customized keyboard configs and such is that once you get used to them, you will have a hard time using any other computer when you suddenly need to. Maybe this isn't such a big problem with physical keyboards, but can be with e.g. text editor configs, which you can't take along if you need to SSH into many servers during a workday and work with whatever is installed there.
I have a bind to turn off all my binds if anyone else wants to use my computer.

And I can still use other people's computers although with some pain.

as a caps-to-ctrl remapper, I can't imagine how crippling it would be to have serious remaps or Dvorak or something and try to use someone else's keyboard. Doesn't seem worth it.
A buddy of mine uses dvorak with a qwerty keyboard and an inline usb switch to engage dvorak. Pair programming and everything.
I actually got used to it pretty quickly. Adapting was not hard.

It's a little like how learning more instruments doesn't make you worse at the ones you know.

I always find this argument nonsense. Most people will be on their computer for 99% of the time and sacrificing for the rest of 1% doesn't make sense. I had a colleague who had been using vim without customization because of that reason and he's always on his computer but I find the reasoning very odd.
Maintaining a Wiki or any sort of extensive note taking operation requires a lot of dedication and I guess practice? Do you have any tips for someone who wants to start out? Is there a smaller step that one could take initially?
I don't use a wiki but instead use Bear (https://bear.app) which gives cross-referential tags and a slick sorted tree of tags. I tag every article ('note') with a set of tags at the top.

#d/2020/05/08 #fam/sis #fam/gifts — notes around a conversation I had with my sister today about potential gifts .

#d/2020/05/05 #recipes/dinner #recipes/c/italian — notes a ravioli recipe I made on 5/5. If I later make it for a group dinner, I'll tag it, too, so I can track when I made things for who and collect longitudinal feedback and recipe changes.

#todo/today is things that need to get done today; things that don't will get moved to other notes.

In case you want to generate a graph of your notes (via graphviz for now), I wrote a project recently (I'm working on a D3 version of the graph "at the moment" although it won't happen until at least tomorrow, today is off-programming day): https://github.com/rberenguel/bear-note-graph

edit: parse error, unbalanced parentheses

Use mind maps. Its quick (much quicker than a wiki) and makes it really easy to reorganise a mess. Freemind/freeplane is good.
Holy shit... that wiki and alfred workflow is INSANE. I am so jealous. Do you find that you're able to discover what you're looking for pretty instantaneously? Any general tips for organizing (sorry if you cover this in the wiki, haven't dived into it yet, but i'm going to!)? also, huge fan of keyboard remapping. I use karabiner, kinesis advantage, and a couple kinesis foot pedals (had some rsi issues, but all this opened my mind to the possibility of experimenting with key mappings and input movements).
Rather than using cmd-tab, using pre-defined shortcuts to jump to the right [workspace,window,tab]; make sure to disable any animations.
Invest in your bash shortcuts! I have shortcuts for almost everything. To give you an example, I work in Rails + RSpec, each class has its own rspec shortcut:

`rspecs alexa_api` translates to `rspec spec/services/alexa_api_service_spec.rb`

`rspecm startup` translates to `rspec spec/models/startup_spec.rb`

I also have a bunch of other shortcuts for repeating tasks like expiring Redis, dumping a test database for local testing, etc.

Save all bash history into a separate file. Even with a high limit, the default bash history functionality has bugs that will destroy your history now and then. With the following .bashrc settings I have commandline history going back a decade:

export HISTTIMEFORMAT='%F-%T'

PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND ; }"'echo \ bash$SHELLNO $PWD "$(history 1)" >> ~/.bash_eternal_history'

I use a 4k TV as a monitor - I can easily see full size my code editor, terminal output, a page of documentation and the web app/site I'm working on all at once. It cuts down tremendously on the back and forth switching and reloading of things that don't feel like they take up much time but do materially eat into things.
Would you mind sharing the model? I tried using my Hisense but it wouldn't work. And I've read that TVs won't always work properly as monitors, but then obviously there's a much wider and cheaper choice of TV panels than dedicated monitors.
2x of these: Samsung UN40KU6290FXZA

You are aiming for something that supports both 4K (3840x2160) [or greater I suppose] and a 60Hz refresh rate in that mode. On cheaper models this can be found on a HDMI2.0 input. More expensive ones might have DisplayPort as an option.

Shop around during TV season and you can find a quality model for $200/ea.

Thanks! Next question is whether I need a new graphics card.
Or better, use 3 4K screens :-) My record of the number of source files being opened concurrently was 10 when I was trying to understand a particularly nasty spaghetti code base.
Isn't it annoying to keep moving your neck around than sticking to the main app window one at a time?
Learning how to effectively use jq, which is kind of like awk + sed for json.
Don't push a commit with a new feature without tests and documentation. Even for your personal projects.

I started doing this a couple of years ago and it's hard to overstate the positive impact this has had on my macro productivity. I can come back to a project I haven't touched in six months and instantly start productively making improvements.

Tests and documentation really are for future you.

+1, good tests are by far the biggest long-term productivity win, in my experience worth much more than any other tooling or process improvement.

Unfortunately I've gone in the opposite direction as you. I recently moved from a company that had a good automated test culture, to one that has a culture of manually testing things, often in production. Everyone, even the senior engineers who've been around for a long time, regularly lands changes that cause prod incidents.

There's actually quite a good canary/rollback system in place to deal with this, so a lot of people think everything's fine. But they don't quite realize how much more efficient things are if you can just make a change and run a test suite, and quickly have confidence that you didn't break things.

Working for Eventbrite really helped we with this. I was there for over five years and got to see the transition from ad-hoc testing and an often broken master to every commit passing the test suite for most teams.

It got to the point where I could drop in on a project by a team in another country that I'd never encountered before, read their README, checkout their code, run the tests, make a change and submit a pull request.

The big thing for me in the past couple of years has been applying the same discipline to my own personal projects and finding that even there my overall productivity improved rather than being held back by the extra work invested in testing and documentation.

Absolutely! I've come to the same realization. Just haven't figured out my effective documentation rules. Difficult to experiment with what works when the feedback loop is on the same magnitude of how long it takes you to forget (eg. 6 months). Best proxy I can come up with is "how can I communicate this to someone who has no context? What would they want to know?"
Automate repetitive tasks that can be automated. A task may take ten minutes. Automating it may take hours, and thus seems too expensive.

If this task is going to be done many times, then the automation WILL pay off. Running the automated task might take less time than the manual steps. And you can be doing something else.

The more of these kinds of tasks that you can automate, the bigger of a lever it becomes.

One of the oldest examples would be 'make'.

Another advantage is that you are less likely to make errors while using the automated way.
And you'll be quicker to automate the next thing, since you have more experience automating.
It also creates documentation/repeatable processes.

Also, learning, though that can be hard to justify.

The automation might, in some cases BECOME the documentation.
I disagree. If your automation isn't well thought out, edge cases might just screw every target and you might have hard time rolling it back.
In my experience, that is the unusual case, not the ordinary case.

Further, when that would happen, it is typically obvious that some bigger change has occurred which required the automated procedure to be updated and tested.

Emacs
It's a useful tool even if you use something else for coding. Org mode is very good. Magit too.
A couple others have mentioned shell tricks. One of my favorites is using Alt-. (in Bash and Zsh) to insert the last argument of the previous command. Press it multiple times and it will cycle through the last argument of all previous commands. It's great for when you want to, say, `ls thing` and then `vim thing`.

Yesterday I went looking for a similar key that would insert a copy of the last argument on the current line, like for when you want to copy or rename a file to a similar name in the same directory, as in `cp some/long/path/to/foo.txt some/long/path/to/foo2.txt`.

I couldn't find a command for this, so I made my own Zsh "widget" and bound it to Alt-/ so now I can type `cp some/long/path/to/foo.txt` and hit Alt-/ to prefill the second arg. I put the code for it up here: https://gist.github.com/dceddia/0a45a88dd61cbdf1be023d0a8f15...

I think !$ will do similar, at least in bash.

(I'm on a phone and normally rely on muscle memory so it might be the wrong symbols).

`!$` is right, though it isn't interactive like `Alt+.` is.
Yes it is, you just need to press Alt-^ to do history expansion on it.
That doesn't cycle through the previous arguments.
Correct.
Maybe I misunderstood, or it does something different in zsh, but it seems like it's inserting the command itself:

    ls foo.txt !$

    ls: ls: No such file or directory
    foo.txt
For `cp some/long/path/to/foo.txt some/long/path/to/foo2.txt` I always liked brace expansion, for example

`cp some/long/path/to/{foo,foo2}.txt`

(Though foo{,2}.txt is even shorter)

Gonna have to try doing this, I usually cd to the source/target directory in these situations, then copy it and use cd - to get back quickly.
I assume you're talking about only on linux? On a mac `alt .` and `alt /` are mapped to characters ≥ and ÷
I'm on a Mac using iTerm, but I think I've tweaked some setting about meta keys somewhere in preferences.
Yes, I love this one! I'll check out the widget. Sounds cool! I have the same problem (it's usually changing filenames, so I just use fzf twice, then modify the second filename).

There was one bash feature along the same lines of this. It was like bringing up the previous command in a shell script, so you could modify it freely, then run it. It was useful for long command, I think. Haven't tried learning it though. Just saw a couple wizard colleagues using it, and it seemed cool.

One of my favorite bash tricks is that I have this alias in my bashrc file:

   function goto {
      cd -P ~/.links/"$1";
   }

And then in the `.links` folder I have symbolic links to directories I need to go to often.

Then getting to a frequently used directory is just a `goto X` away.

Cool. How does that compare with setting CDPATH?
I just looked up CDPATH and my understanding is that the difference between the two is that with CDPATH you are setting directories that you can quickly navigate to subdirectories of.

This is more of a quick link to directories themselves.

Maybe you could do something similar to the alias if you had my `~/.links` directory in your CDPATH, but then you'd still need to add the `-P`every time to get it to follow the symbolic link.

Not something I had ever thought of before honestly.

Ooh, that's cool. You might be interested at z[1]. It kinda fills the same purpose as your trick, except it automatically figures out what are your most used directories by tracking your shell navigation or something.

[1] https://github.com/rupa/z/wiki

$_ will do the same thing in bash as in "ls thing" and then "vim $_" (but only works for arguments from the last command)
Thanks! I didn't know about Alt-. I'm using powershell and it works there too.
Efficiently using multi-select to edit multiple lines simultaneously (e.g. cmd-d in Atom)
Mildly off-topic but I find that exercising in the morning or during lunch break gives me the biggest efficiency boost ever.
I play the Eleven Table Tennis VR game for ~1 hour at 9PM, become sweaty, take a shower and then I feel like I can very productively work until 5AM. Quarantine weird schedule, but it works :)
There's many tools I've picked up over the years (sometimes on as needed basis, sometimes just for fun). The latter has been way more rewarding though in retrospect :) Instead of enumerating all of them, I think this course page does a great job of collating them by topic: https://missing.csail.mit.edu/
This is awesome. I remember stumbling upon it at some point, but totally forgot about it! Gonna definitely check it out.
Get a larger, higher resolution monitor. And when you can't do that get another monitor.

My main one's 5k2k and I could still use more space.