I normally have tmux sessions (one per project) so I can quickly switch between them without closing/opening new terminal windows, cd'ing, etc.
I also have some automation that allows me to run particular tests from within vim such that it runs in a separate (designated to tests) tmux window.
I really love my setup (even though, at this point, it's probably more out of habit than anything else) and I don't want anything else.
But. The other day I've been pairing with my mate Josh and he kept doing this one thing over and over again and it was such a basic thing, yet such powerful thing at the same time, that I could feel my perfect cli world shaking.
You see, Josh runs tests in a shell and writes code in a gui editor - Atom. When a test fails, there is a stack trace and he can click on any line there and the editor pops up with that file opened. It looks like this:
Compared to the steps I go through to open a file from a stack trace on a particular line, there is a world of difference. It's a game changer in fact - it makes me like stack traces, want more stack traces and better ones too.
So I absolutely had to have that and I am pleased to report you that it is possible in a pure CLI world. It's limited and hacky. There's some custom setup. It will be confusing the hell out of you every now and then. But it works for the most part and that's what matters.
Anyway, here goes the magic:
We need a terminal emulator that has a feature "click on a thing that looks like a filename and pass it to a script". The only such terminal emulator that I am aware of is iTerm2. Sorry Linux folks.
Configure iTerm2 "Semantic History" command
Semantic History is an iTerm2 feature that lets you click on a file path or url while holding ⌘ and have that file/url opened in a browser or default editor. It is also possible to change the default behaviour to something else. And that's what we need to do:
Create a script file
Mine looks like this:
#!/usr/bin/env bash set -e /usr/local/bin/tmux select-window -t vim /usr/local/bin/tmux send-keys Escape /usr/local/bin/tmux send-keys ":e +$2 $1" /usr/local/bin/tmux send-keys Enter /usr/local/bin/tmux send-keys zz
Things to note here:
- path to tmux command should be absolute
- this script assumes tmux session has a window named
vim. This is my personal convention that each session has one, but your workflow is likely to be different so you'd probably want to replace
select-window -t vimwith something else.
- Only works for absolute paths
- If you have more than one tmux session it may start opening files in some other one - not the one you're currently looking at! This is very confusing because it looks like nothing is happening. But I figured
tmux xyzwill run against last active session (where any activity such as keystrokes occurred). So the only time this problem will catch you is when you switch to another session and the first thing you do is click on a filename.
Mr. iTerm himself helped me to work this all out so if you reached this part please say Thank You here: https://gitlab.com/gnachman/iterm2/issues/6861