Hacker News new | past | comments | ask | show | jobs | submit login
Use fzf for tmux session switching (waylonwalker.com)
179 points by samesense on May 8, 2022 | hide | past | favorite | 57 comments



I still don't quite understand the value of tmux, at least on a modern machine. If I need another terminal, I just pop open another terminal window and tile or tab it. If I want to keep a set of terminals organized, I use workspaces (at the OS level).

I can obviously see its value if there is no window manager or desktop environment on the system I'm using, but that's rare these days–if I'm working on a system with neither of these it's always over ssh. With a WM or DE it seems like tmux just adds a redundant layer of organization. What am I missing?


You can ssh into a system and use tmux. Then you can detach from the session and when you come back a week later your tmux session is still there and you can continue with no friction. Also i find it interesting that you said you don't see its value and then continued to explain its value. For me it's definitely more common to work with systems/servers without a DE and WM. It's just better to handle this problem at that level instead of at the terminal level because then your shell setup becomes terminal and platform agnostic. With mouse support turned on tmux feels almost like a WM in the shell, which is amazing.


I’m a huge fan of `tmux -CC` for stuff like this!


I didn't know about this. For others, it's called tmux control mode, and integrates tmux within a terminal emulator for things like split panes and tabs. It requires terminal emulator support. Here's some documentation: https://github.com/tmux/tmux/wiki/Control-Mode


Are there any Linux terminal emulators that implement this? So far the only I've encountered is macOS's iTerm 2 and it's brilliant but mac-only.


You want to be able to disconnect and reconnect to your terminal session on the fly for any of a number of reasons:

- You're connected to a remote host and you don't want an unexpected network issue to kill your session

- You want to be able to periodically check on the status of something on a remote host but don't feel like keeping the connection open all the time

- You want to connect to the same session from different clients

- You may need to restart you graphical session and don't want that to kill your terminal session

A really simple way you could get this working is what abduco and detach do: the demon just blindly shuttles input and output between the client tty and the virtual tty that the interactive process is running in. However, when you reconnect to an existing session, you get no context, because the server doesn't know what it would need to tell the client for it to reassemble the tty state.

In order for that to be possible, the daemon would need to keep track of the terminal state internally. It's really annoying that that's necessary because now your actual terminal emulator isn't directly communicating with the process it's displaying, and you won't be able to access any features of your terminal that the daemon doesn't support.

But once you already have this background process that's keeping track of terminal state, you might as well build in other features that would require that, like window management, otherwise people who want those features will end up having yet another layer of terminal. If you don't want those features, you can pretend they're not there.


Imagine you're at work, and you have tmux running with 15 sessions to various machines. You go home, connect to that tmux session and you can keep working without having to re-connect/SSH and log into 15 machines and just continue where you left off.

It's sort of like being able to RDP into the machine you were working on except it's text-based.


So something like abduco (https://www.brain-dump.org/projects/abduco/) should do the job too? I think GP's comment was more concerened with the terminal multiplexing, not the ability to detach a session.


abduco claims to be a tmux alternative, which there are probably a few - I don't think any of these points being made are attempting to claim tmux is the only tool with these features, only that the features are very useful - tmux just happens to be one of the most popular tools in this category of tools


I see, thanks! This sort of use case would be rare for me, but when I've needed to manage sessions I've used screen. I can see how tmux would be valuable for managing more complicated groups of sessions like you describe.


You lost me at go home and keep working...


tmux is a basically all of the modern features of terminal management but scriptable.

So you can have tabs, splits, sessions, etc, all scriptable. Eg if I hit F1 in the shell I automatically get the command’s man page alongside the interactive shell.

I’ve also used it on occasions where I’ve needed to pair program with someone on a poor internet connection. We’d SSH into a common area and share a tmux session while chatting on a regular phone call. Thus no bandwidth heavy video conferencing.

It’s also been handy back before I worked fully remotely, I’d have a dedicated desktop running tmux and when I got home I would VPN into the office and resume the tmux session so I could resume where I left off.


On Vim there's a plugin called Vimux which allows me to control other pane from Vim. For example, I type `<leader>l` and it runs the last command on the next pane, which usually is a command to test the code I'm working on.

Sure, you can do everything in a WM or DE, but I use Linux and macOS and it's nice to have the same configuration, keybindings and environment everywhere. I also find tmux more customizable than Gnome Terminal and easier to setup than st or urxvt.


You can do everything from the keyboard. No need to ever reach for the mouse. Ever. Once you master it (the learning curve is a bit steep though), you'll never want to go back. I do use my own customized key-bindings.

Also - for long running processes, you can run stuff in a tmux session, go to bed, and wake up hours later and see exactly what happened. You can make the scrollback buffer as big as you want. My scrollback history is 50k lines, and that's totally fine. Of course the history is searchable with vim commands which is also nice.


One of the first reasons I starting using screen (switched to tmux later) for local terminal work was so I can re-open it if I accidentally closed the window. It's still one of my reasons for using it.


If you like tmux, take a look at zellij (https://github.com/zellij-org/zellij), it is a modern alternative that has a lot of nice features (either developed, or on the roadmap) that tmux is missing.

Have no relationship to it, just a happy "customer".


Wow this is the first time I've ever seen a comment that genuinely made me feel like an old gray beard.

I remember getting into Unix just a little before the time tmux came onto scene as the modern alternative to screen, and being in awe of all the people who had used screen long enough to have a list of things that could be modernised about it.

Now tmux is in that position!


I only started using Tmux when I installed CentOS 8 on my work PC in 2020 and discovered that GNU Screen was no longer the default terminal multiplexer. I figured it was about time that I “get with the programme”. Now, I’m starting to feel increasinglylike Abe Simpson: https://invidious.kavin.rocks/watch?v=5DlTexEXxLQ


> Wow this is the first time I've ever seen a comment that genuinely made me feel like an old gray beard.

Here's a nickel, kid...

https://en.m.wikipedia.org/wiki/DESQView


tmux is still the "new cool kid" for me :-D it took a while for me to migrate from screen to tmux, it probably going to take a very long time to migrate off tmux (not that i have any reasons to)


Interesting, reminds me of dvtm [1]. But I am sure there are more takes out there on “window management” in a terminal as I have not really explored this space much.

[1]: https://github.com/martanne/dvtm


For layout in Tmux you can checkout https://github.com/pallavJha/chaakoo too.


Unless there's something like byobu, I'll stick to tmux for the time being.


tmux sessions are incredibly useful for keeping multiple projects organized.

i just wish i could connect to remote tmux back ends and recover windows as organized locally after a network cut.

so the local tmux presents the ui and performs session management, and the remote tmux backends hold the shells to provide network cut resilience, but still rely on the local ui instance for all user interaction (so cut/paste buffers and mousing and such are preserved)


Modern ssh supports forwarding of Unix domain sockets

On remote host:

    $ tmux -S /tmp/remote.sock
    <now detach from session: prefix d>
On local host:

    $ ssh -L /tmp/local.sock:/tmp/remote.sock user@remote
    $ tmux -S /tmp/local.sock attach

I Typed this on a phone and not validated but it looks good to me right now


Have you tried this before? As far as I can tell, tmux expects to pass the client's terminal fd over the unix socket. When I try it, I get something like this in strace (passing fd 7):

  > sendmsg(5, {..., msg_control=[{cmsg_len=20, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, cmsg_data=[7]}], msg_controllen=24, msg_flags=0}, 0) = 16
And then the client relays an error:

  > open terminal failed: not a terminal


I hadn’t, i just tried it now and yeah it doesn’t work :thumbsdown:


6 months or a year ago I started using "mosh" to connect to my main machine from my laptops, and I run tmux on that machine. When I have a network cut, I just wait a few seconds and it's back in business, whether that's moving locations (I use a VPN so my IP is always the same, currently Nebula but has been wireguard and ZeroTier in the past), legit network problems, switching to my cell phone...


i've done this with mosh in past which gets you part of the way there.

problem is that it then doesn't work for local sessions. so you run it locally, which gives you local sessions and window management, but then all remote connections have to be via mosh -or- you mosh into the datacenter which is good for accessing infra, but leaves you having to run a separate instance for local work.


Agreed. In my case, all my "local" work is on my workstation via mosh, and my datacenter work is also done in that same tmux session. My laptop(s) are just thin clients for that work. That's great for the Chromebooks, but kind of a shame for in the case of a more capable laptop... For my workflow though, it works well.


Can you elaborate further on what gain I would have by having the tmux UI "rendered locally" on my system vs the SSH host? I'm obviously missing something based on your description.

For example: SSH into server, start tmux on that system. If I am disconnected for some reason, SSH back into server, tmux attach -t 0 (or whatever ID I have) and I've recovered my session. Cut/copy/paste, mouse use, etc., are all treated as they are through any SSH session.


a sibling comment suggests a reason:

> the local tmux then remembers history and allows looking up commands on the remote shell, that would be huge.


This is exactly my set up as I work on a number of remote systems daily.

I have an "outside" tmux session that can be run at either my desktop or laptop. When I start fresh, I open an outside tmux session and run a startup script. This preloads my outside session's copy buffers with named passwords from the `pass` password manager and creates windows to each of my remote sites. The shell for each of these windows is set to a script that does a simple loop of network check than attempt to ssh to the remote site. This ssh connection has an environment variable set that my remote bashrc will see. When this variable is set, my remote "inside" tmux connection is automatically recalled (or created if it doesn't exist.)

I have a script runs when I put the laptop to sleep that kills all the SSH connections cleanly, and when it wakes up again, every window reconnects to the remote machines and opens the remote tmux connections again. Everything is exactly where it was before and needs no intervention.


+1

If the local tmux then remembers history and allows looking up commands on the remote shell, that would be huge.

Currently all my local work is saved but ssh into another machine? All that work is lost forever unless I explicitly save it.


Isn't this just:

$ ssh <hostname>

$ tmux --list-sessions

and

$ tmux --attach-session -t <session #>

?


I had this problem myself when using tmux (how to switch sessions quickly and easily).

I ended up writing a shell script [1] to use fzf to display a list not only of sessions, but the windows within each session.

Which I invoke from tmux like this:

bind C-a run-shell -b "$HOME/.local/bin/ftwind"

This has become so ingrained in my tmux workflow that I would be utterly helpless without it.

[1]: https://github.com/anelson/dotfiles/blob/master/home/.local/...

EDIT: for formatting


If this tmux-fzf setup could be augmented to perform preview and grep not only on window name but also window contents then I'd consider migrating from the already built-in `choose-tree -Zw` command.


    rpick() {
        session=$(for i in $(tmux list-sessions -F '#S'); do
            echo -e -n "$i\t"; { { tmux capture-pane -p -t "$i" | tr '\n' ' '; } || true; }
            echo
        done | fzf --exact --reverse | cut -f 1)
        if [[ "$session" != "" ]]; then
            tmux attach -t "$session"
        fi
    }


I'm still trying to assemble a way to put together the pieces to not only return to tmux sessions after detaching, but after detaching and the underlying server reboots. Playing around with CRIU, but trying to make it all automagic with nested PIDs, restore the screens and shell history buffers just how I left them, and implement the common use case of automatically re-establishing ssh connections remains a challenge.


I've never used this myself, but you're describing what a coworker used to recommend when that topic came up many years ago. See the bottom of this page about byobu.

https://help.ubuntu.com/community/Byobu

I'm sure there are newer/better? tools someone might recommend here too.


Another reason for using tmux: never worry about changing your muscle memory for splits and nav ever again.

I've been using tmux for five or six years. In that time I've used Linux and MacOS and several different terminals. But how I navigate around a terminal has stayed the same thanks to tmux.

Another reason: put complex tmuxinator configs in source control and start up a bunch of stuff for your project with a single command.


Your last point is why I use it. I think many don't know you can configure it to open apps, run commands, and open splits on start. Super helpful when projects get big!


Once I discovered fzf a couple of years ago, I instantly knew it was the future of shell. My entire workflow is now driven by fzf. I use it together with bash, vim, cd (and "z" command), even mkdir (autocomplete from "words" file).


> and "z" command

I use zoxide now, it's slightly faster.


I've a much simpler solution. I nest tmux sessions. In the top-level session every window is named the same as the session that is attached in it. I've two different prefix keys: ^T for the top-level, and ^A for the level below. Plus I've a one-liner (well, shell function) for mapping PIDs to session & window. Plus a script to create new nested sessions, and a script start $EDITOR in a window of the current session (with the window named after the file being edited). Plus I've a half-baked script to set up this environment, with one nested tmux per-project.

This allows me to have a very well-organized way of working over ssh.


I really like iTerm2 for Mac. The tabs, splits, and navigation, are intuitive and powerful. I haven’t found a need for tmux. I use fzf for file finding, it looks like this is use is a subset of iTerm2 capabilities


The only macOS app I miss on Linux


iTerm2 has `tmux -CC` compatibility. That means when you SSH into a server over iTerm2, you can type that command and get tmux integrated with iTerm, with all the regular window splitting, resizing, tabbing, etc working natively on the terminal emulator.

Essentially you get all tmux functionality on the remote but with the local ergonomics you're already used to.


Video is cut off on mobile


The entire site is weirdly mobile (or perhaps just mobile Safari) unfriendly.

The home page also has some issues with elements clipping/overlaying and not registering clicks.

I say weirdly unfriendly because the graphic design is very $CURRENT_YEAR, which is usually designed mobile-first (since that’s where most of the traffic is these days). But the author clearly spends more time on the desktop (the article _is_ about tmux) and didnt check how it performs on mobile.

If it is just a safari issue I’m sympathetic. Testing for safari is a nightmare if you don’t have Apple hardware available.


Yes I had the same, after about 2 minutes things became weird and cut off.

Seems like a transcoding error for certain devices only then, if nobody else noticed it.

Unrelated, but it was completely impossible for me to put the video on full screen. It seems like the site did something with the scroll that prevented me from scrolling horizontally to click the full screen button.


Nice, I just extended this to kill a session too. This is great.


It is interesting how much people use tmux for working in several interactive shells at once. I tend to use tmux more for running servers in detached windows.


I use it to manage my dev environment with a bunch of sessions.

One for my blog, podcast, 2 side projects, contract work, etc.. I usually have 6-10 sessions. Although I don't use fzf to search through them. The built in leader+s key makes finding and jumping between sessions painless, you also get the benefit of being able to see a preview of what's in the session.


I tend to use one tmux session per project. I usually have 2-3 open for various client projects, one open for my TIL repository, and then I go from there. Within those sessions I tend to have separate windows and panes as a way of organizing any (web) servers and other long-running processes. The 'first' window of each session is usually a split between Vim (where I'm working) and zsh (where I'm executing git commands, running tests, etc.).


I've wanted something like this but for "screen" for a long time. Does anyone have such a solution?


Could someone, in brief, tell me what fzf actually is. The man page is uninformative.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: