DEV Community

Cover image for How I navigate tmux in 2021
Waylon Walker
Waylon Walker

Posted on • Updated on • Originally published at waylonwalker.com

How I navigate tmux in 2021

In 2021 I changed the way I navigate between tmux sessions big time. Now I can create, kill, switch with ease, and generally keep work separated into logical groups.

🔗 Check out the post on https://waylonwalker.com/tmux-nav-2021/ to speed up or slow down the recordings.

Chris Toomey's Tmux Course

I took Chris's tmux course in December 2020 and it was fantastic. Even as a seasoned tmux user, I learned quite a bit. Before the course, I was proficient in navigating within each of my tmux sessions but rarely started more than one session. A few months later, I have adopted a lot of what I learned from Chris and made it my own.

I am now keeping projects to their own session and can move between them fluidly with just a few keystrokes. For high-traffic projects, I have them bound to a single keystroke for instant switching. This change has been a game-changer from the mess of windows I used to have and the nightmare it was to find work I was doing and end up duplicating project work in two separate windows.

📝 NOTE: Some of my config comes straight from the course, and some of it has been extended to my liking.

Let's take a quick look at how I am navigating through tmux on a day-to-day basis.

👆 Overview of how I navigate tmux

tmux ls

Throughout this article, I have several recordings showing how I use manage sessions with my keybindings. I will often run a tmux ls command to highlight running sessions at various points to help guide the viewer.

ta

my attach/session switch script

At the heart of my tmux navigation is a highly customized version of Chris's tat script that I renamed ta. Many folks add this to their bashrc alias ta=tmux attach. Simply calling ta will do the same thing as shown below. If you're in a tmux session, it does nothing, and if you're not in one, it will attach you to the first one.

get the full script from GitHub.

👆 attaching to a session by default

In my ~/.bashrc or ~/.zshrc I add the ta command to keep myself in a tmux session at all times. Whenever I open my terminal, I am automatically dropped into a tmux session, but if I am opening a split while in tmux it's smart enough to know not to nest tmux sessions.

ta
Enter fullscreen mode Exit fullscreen mode

Another article can dive into my ta command. This one is more about the methodology, workflow, and keybindings to get me there. It's available in my devtainer repo.

but there's more

gettin fuzzy

Give it a directory, and a fzy dropdown will let you choose a subdirectory to start your session in, and name the session after that directory.

ta ~/git
Enter fullscreen mode Exit fullscreen mode

🔥 Bonus, use direnv to automatically set settings, echo your git status, activate your environment or whatever else you need.

👆 give it a directory, it will ask for input to which project and start a new named session in that directory.

Note that starting from outside currently does not start in a split layout like it does when starting from within tmux. I am still playing with this, but generally, I want my terminal session to be plain when I first start my terminal. I usually am starting work after the first default session.

🤔 I still use both fzy and fzf. It probably doesn't make sense to use both, but I am currently giving fzy a try.

prefix+w

tmux choose-tree

By default, tmux comes with a tmux choose-tree command bound to prefix+w, which opens in full screen. The upper section of the screen will show every window opened. While selected, you can show the splits in each window by hitting l, or fold it with h. You can search for a session name by hitting /.

# ~/.tmux.conf

# expanded to show all splits
bind s choose-tree
# simpler window to show only sessions
bind S choose-session
Enter fullscreen mode Exit fullscreen mode

Keybindings in choose-tree/choose-session

The default keybindings of the tmux choose-tree and choose-session that I use are listed below. J/K are very intuitive, but I just learned about h,l,/. When I do use one of these, the / (search) can be super helpful to find sessions/windows faster.

action key
fold h
unfold l
up k
down j
search /

prefix+c-w prefix+c-g

open a project

I have set up to make it easy to open my non-work projects (in my ~/git directory) and my work projects (in my ~/work directory). I bound prefix+c-g and prefix+c-w to open a new session in their respective directories. I like mapping common prefix commands with control to keep my pinky mashed on that control key.

# ~/.tmux.conf

bind C-w new-window -n "work-session-picker" "ta ~/work"
bind C-g new-window -n "git-session-picker" "ta ~/git"
Enter fullscreen mode Exit fullscreen mode

prefix+c-j

jump to session

Now that I have ta rocking with a good create or attach setup, I am rarely toggling through a list of running sessions, but I am doing it with prefix+c-j when I do it. Keeping my finger on control and pressing <space>+j. This keybinding uses fzf to fuzzy match to an existing session and attach.

bind C-j new-window -n "session-switcher" "tmux list-sessions | sed -E 's/:.*$//' | grep -v \"^$(tmux display-message -p '#S')\$\" | fzf --reverse | xargs tmux switch-client -t"
Enter fullscreen mode Exit fullscreen mode

M-N M-P

next/prev

Next and Previous sessions. This is super handy when working with under 3 sessions to be able to cycle through sessions holding shift+alt and pressing n or p.

tkill

time to clean up

It's easy to get a long crufty list of sessions running throughout the day. Typically this is not too bad on system resources compared to running vscode in every working project, but it does make it more challenging to manage and wade through the sessions list. I use a handy shell alias that's been in my zshrc for quite some time.

alias tkill="for s in \$(tmux list-sessions | awk '{print \$1}' | rg ':' -r '' | fzy); do tmux kill-session -t \$s; done;"
Enter fullscreen mode Exit fullscreen mode

I don't have this one set up with a nice hotkey, but it works for my fingers. I often pop open a lower split(M-s), run tkill, and close (M-x).

Last Session

back

While M-n and M-p work well with a small, focused number of sessions, I often end up with too many sessions open, and it's not efficient to remember a double M-N followed by a triple M-P to get back and forth. Most often, I want to get between two sessions quickly, no matter what the order is.

bind -n M-B switch-client -l
bind -n M-b switch-client -l
Enter fullscreen mode Exit fullscreen mode

Once I get two sessions back to back, I can switch between them with insane speed and precision.

More Precision

one keystroke

The final layer of precision is for my most current project. I need to get to these with a single keystroke. These are bound to a set of keybindings that were readily available, just above the home row.

bind C-t new-session -A -s todo "cd ~/work/todo && nvim -O backlog.md doing.md done.md"
bind -n M-i new-session -A -s ww3 "cd ~/git/ww3/ && nvim"
bind -n M-o new-session -A -s images_waylonwalker_com "cd ~/git/images.waylonwalker.com/ && nvim"
Enter fullscreen mode Exit fullscreen mode

These few directories are always at my fingertips, encouraging me to keep better notes

And yes, I did steal this last one from Harpoon-man By The Way.

Hub and Spoke

M-i M-b

I have really been digging this hub and spoke workflow where I am rocking away on a project hit M-I, take some notes then hit M-b to get back to where I was.

hub and spoke

Model of my current workflow

Example workflow

  1. open tmux session with ta
  2. prefix+c-g start work in a project using a fuzzy matcher
  3. M-t over to my todo list
  4. M-b back to my project
  5. M-i to my blog to look up notes/make notes
  6. M-b back to my project
  7. prefix+c-g start work in another project using a fuzzy matcher
  8. M-t over to my todo list
  9. M-b back to my project
  10. prefix+c-j fuzzy back to the first project
  11. M-b back to the second project

Please let me know your thoughts. @waylonwalker, this one took me a bit longer to put together with all of the animated gif's, but I think it helps visually show how I navigate tmux every day.

Please give it a share if you liked it

If you liked it, give it a share and tag me on twitter. I don't often ask but this article took a bit more to put together than my normal post.


Check Out These Related Posts

https://waylonwalker.com/symlink-gallery/

https://waylonwalker.com/neovim-live-substitution/

https://waylonwalker.com/find-replace/

Top comments (4)

Collapse
 
y1450 profile image
y1450 • Edited

Sorry for spamming the comment section.
I created this dev account, just to appreciate how much I like your content/website.

I can recall the days of the broadband internet days where most the content was text based. Today, there is a explosion of video based content and there are pain to annotate.
I really like your website, short to the point, the gif content on the site is kept locally, so one can use it offline via rss feeds. one can rg for quick lookup. the content can be accessed completely offline.

I would love to see your rss workflow and some post on rss in general.

Collapse
 
akhilnaidu profile image
Akhil Naidu

Wow! The idea of individual and small clips is so good. You sure are capitalising on the beta feature of the video uploading.

Anyways, this is a great way of presenting content.

Collapse
 
waylonwalker profile image
Waylon Walker

I just started leveraging the beta feature of video uploading in some other posts such as this one.

The embeded videos here are actually self-hosted on my blog, you can see if you inspect element, the source still points to me 😁

Collapse
 
cainnz profile image
cainnz

On your tmux config, it is possible to remove the [0] located on the lower left corner?