We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
Analysis Summary
Worth Noting
Positive elements
- This video provides a clever, low-dependency solution for clipboard synchronization using standard Linux primitives (FIFOs) rather than proprietary software.
Influence Dimensions
How are these scored?About this analysis
Knowing about these techniques makes them visible, not powerless. The ones that work best on you are the ones that match beliefs you already hold.
This analysis is a tool for your own thinking — what you do with it is up to you.
Related content covering similar topics.
Transcript
today I'm going to be talking about how I've set up clipboard sharing to my remote development environment and to give us some context starting off I want to talk about that development environment so for years I've just been using Linux installed on a PC or a laptop and I would do all of my tooling there coding there still works great love that model but about six plus months ago I decided to move purely to a virtual machine where I built my development environment using tools like NYX OS and the Nyx package manager and created an environment from scratch and the benefits here are that I can rebuild it I can make portable images that can go into Cloud providers or be run locally it all works really really well for me and then the great thing too is that my client machine doesn't actually have to be you know a beefy machine let alone does it have to be a specific operating system I mean heck I could even use Windows as long as I can do an SSH connection into my Dev environment I'll have access to everything I need additionally the VM doesn't even have to run a desktop environment because the tools I'm primarily using to get my work done are things like tmux and neovim and those work amazing through ssh in fact even if I did want to use a more graphical application like let's say that I wanted to use vs code I'll just say VSC for here it has plugins just like IntelliJ does that can go through SSH connections and plug into some kind of backend VM presenting my files as if they were local but largely when I'm saving it's just persisting onto this this virtual machine and all in all I just think this is an awesome model because I'm someone who works in Linux a lot I don't really want to care much about what my client machine is to be super honest with you and while there are tools like Docker desktop and stuff to try to help give you some of the Linux Primitives those are running VMS under the hood too in fact Docker desktop is largely abstracting qmu for you setting up that virtual machine giving you container access so this builds everything out for me and again decouples my client machine and you know maybe the last thing I'll say on it is I don't do this a lot but it's kind of cool knowing that I can do it let's say that I'm actually running this in AWS on a given day so my remote development environment I have the ability to modify that virtual machine's CPU and memory at any given time so if I wake up one morning and I'm going to be compiling Firefox from scratch and it's a big task and I want a lot of cores well I can just for a couple hours and I need that work spin up a larger CPU granted I will pay for it and I have a much more powerful development environment without actually having to change out my client there's hopefully going to be far less need for an upgrade of a laptop or anything like that now this model hopefully I've kind of sold you on why it works at least well for me not saying that you should necessarily do it but one of the interesting things that I constantly ran into was sharing the clipboard and the clipboard turned out to be quite challenging to share initially and here's why so if you've ever used a tool like Fusion or like parallels you might know that clipboard sharing is there but I don't want to use Clipboard sharing through one of these apps primarily because it's not portable if I'm running locally on Fusion one day and then I'm running an AWS the next day I don't want the clipboard mechanism to be different another issue is that my VM isn't running a desktop environment I don't need gnome I don't need I3 everything's going through tmux and neovim or a remote session through a code editor no need for that and because there's not a desktop environment there's actually not a concept of a clipboard for the most part so what I really needed to do here is find a way to create like a Channel or a buffer or a first and first out cue that I could send data to that I wanted to copy and have my Mac slurp that up as it gets put in that buffer now if that sounds at all familiar to something I've talked about recently that's because the solution was using named pipes and named pipes I just released a blog post and video on this a couple days ago you can check them out if you've never used them but using named pipes I was able to just reuse this simple Linux primitive to do exactly what I was hoping to do so with all of that context in place let me take you into my development environment and show you how this is all set up starting out I am just inside of my client machine and you'll notice that there is a tmux session happening this is all completely local I've got the markdown file for the page I was just showing you and so on this is not using that remote development environment at all currently I have my remote development environment running in my home lab so I'm going to SSH into a local IP address and then the first thing I do once I'm inside of that development environment is I run tmux now running tmux does a couple things for me the first thing that running tmux does is it sets up another team up session so I actually have two team up sessions mapped to different leader keys so control L is going to let me do things inside of this server-based environment and then the normal leader key control B is going to let me jump around inside of the develop or the client machine in this case and that background change where it's like gray to dark black I don't know if you can see this inside of the the video but that also gives me some contextual awareness of where I am now to set up the clipboard the first thing I need to do to make this possible is make sure the named pipe exists so on my machine I put this at my home directory in a file called clip the way that I created this named pipe were first in first out queue is that I did a make fifo command so make fifo and I did that for clip with clip in place now I have a first and first out cue I can have applications forward information to it and eventually I can have my client machine receive information from it as well so let's say how we do this in tmox if you're not super familiar with tmux I'm sure many of you are a lot of times with tmux we run a command where we scroll up inside of tmux and we want to select a bunch of text maybe it's logs and whatnot and then we will copy this kind of selected buffer into our systems clipboard but I don't have a system clipboard in this case of tmux so I'm going to open up the default config file for tmux which is homedirectory tmux.conf and we're going to go down to the clip option and I'll talk about these two options that I use so in the first option what we're doing and in my case I'm using vimkeys and tmux you can kind of look up how to do this if you're interested so when I'm doing copy mode VI for the y key I want to run this command I want to run tmux Showbox offer in in that show buffer command it is going to forward it to clip or the named pipe just like that that's all it is if you were using like an X window based Linux machine you'd likely have a forward command where you were sending it to something like x-clip but this is effectively the equivalent and then another thing I do in tmux is I do enable mouse interaction so when the mouse drag happens and this event triggers the mouse drag and pane one I actually do a copy selection as well all of this you know Snippets will be in my blog but when I do that copy event I want to run the exact same command so whatever selected take that buffer forward it to the named pipe so as long as my client machine is accepting it we're all good now you've got kind of some context around tmux now I'm going to talk about Vim before I pair them together so let's go to a file we'll go into let's see just a development project I'm working on right now and let's open up a file inside of it all right so here is a go file this has this is all inside of the machine so obviously I have all of the auto completion and everything that you'd expect in a development environment now oftentimes in Vim we select something and we want to paste it but Vim has kind of two modes right it has yanking it also maybe even three it has putting something in a register and then it has just arbitrary commands we run so if you're familiar with vimsyank I actually don't want to change the default behavior of yank I want to keep it as is and I even don't want to mess with like the registers like the plus sign register that oftentimes gets assigned to a clipboard I don't want to play with that whatsoever what I do want to do is set up a custom command for Vim where effectively when I use my leader key which on my machine is assigned to the semicolon and then with the leader key I use let's say c as the character I think that's what I've got it mapped to I want it to do this same action so basically when these get clicked together let's put some space in here to make it easier to read when these get clicked together I want to run the current buffer right or current let's call it current selection because it's going to respect visual mode and visual block and I want to send that current selection over to my clip file so very similar to tmux just some different nuances around how Vim will handle this all right so let's see if we can do exactly that so I will maybe open up a new tab here and let's go to we'll Escape out of this we're going to go into my vimrc which I am using neovins this will be into config it will be inside of nvim and it'll be in the init file here okay so now we're inside of my init file and I'm going to take you to where I've got the clip specified now there are like three ways that neovim can be set up or Vim can be set up maybe you're just using vim and you have a vimrc I'll put a snippet for how that might look in my blog perhaps you're using neovim and now you have the option of using Lua or vimrc I am doing it in Lua inside of a init Vim file because I'm still a bit in legacy mode I haven't converted everything to Lua but the function definition is pretty simple overall right so basically what we've got here is I've got a function called save selection to clipboard I set up this somewhat verbose command which I won't go into all the details but it's basically going to take my current selection and then save it out to this clip file then I use the Vim API keymap setting and this is going to allow me to specify that when I'm in visual mode and I hit leader C I am going to run that save selection clipboard command that I just described to you so that's sort of our function definition if you will and how we call it from an api's perspective all right so now assuming you believe me we've got this set up in tmux and neovim we'll now look at attaching the client to this named pipe or fifo queue and see how data can be pushed back and forth now let's hook up the client machine to the remote development environment I've specified in tmux the dev tab which is the VM and client which is the local machine now as described in that diagram the actual connection is just done through another SSH connection so it's not the most elegant solution but it works super reliably for me if we can just establish an SSH connection run a command like cat or something else it'll actually just sit on that fifo queue and wait to be able to read something off of it and as you'll see in a moment we can eventually wrap this in a loop so that every time we maybe lose connection or pull something off we just reconnect and do it again and again there are flaws to this like you have maybe another client somewhere that's connected and you know all kinds of kind of chaos but I never really hit that this works super well and is super simple for me so let's attach I'm running the sh command and now I'm kind of stuck wanting to cat out the contents of that named pipe but there is of course nothing inside of that named pipe so now we'll go back to the development environment and let's do something like a let's see let's cat something from it and let's cat the contents of CPU info so we'll scroll up inside of tmux and let's say I want to copy to a web browser or something some content about it there's obviously a lot of output here because every single processor is listed so let's just go up and up and up all right CPU info at the very top so on this environment I will go ahead and use my click and drag to just copy something from here and when I let go it will trigger that mouse event and should effectively copy the clip if I go back to my client you can now see that my client has pasted out all of that stuff that I just copied so it's instantly in the clip Board of my client machine now I'll go back to the development environment and let's try Vim again which I think one of these yes this one here I have PEX so we will do this and let's say that I'm copying some code to send to someone on slack this time so I'll go into a file that I know has a bunch of code in it and we'll grab this full function so I will go through and grab it and what I'm going to do here again is I'm going to run my leader key with c and now Vim actually is kind of Frozen up and hanging with this little indicator in the bottom left that it is sitting on clip now the reason is because the client is no longer connected right it already did that output from tmux so it left the SSH connection finished its job and we'll talk about how again we Loop to make that not happen in the future but for now if I just reconnect with cat clip there is the function definition that I just copied out of my development environment using that command and now back in the development environment my cursor is free and I'm able to do whatever I want all right so kind of the last thing is talking about how to make this work as kind of a constantly running thing the right way to do it is to use in a knit system like system D or on a Mac system you can use launch D Homebrew has some abstractions you can use to set it up where you're actually constantly running this I'm not going to go through all the different modes that you can set this up because init systems are your choice so I'm just going to do a really naive implementation where we basically do a bash script which could work where we say while true and then we just run do and we will copy this SSH command and paste it in and then we will say done and now we are constantly doing this command we're going to sit and wait and then as we do different actions stuff will print out so let's go back to them and we'll copy just a couple lines so first we'll copy this length line so copy that and then we'll go down and copy what's something that would be more distinct let's do this function definition so we'll copy this run that same command and then I'll go back to the client and you can see that first it grabbed the length Ops then it grabbed the Linux inspector and it's just going to continue to print and print and print and print so as the very last step of all of this if we just exit out of that loop I will mention that what we want to do is instead of catting clip which actually will work we actually want to just put it into our system clipboard so let's do just the s SSH command one more time and out of the SSH command we will put it in this case I'm on a machine that uses PB copy to command line get it into the clipboard and if we just run this command and wait on it again next time I copy rather than it printing it out it's going to put it inside of my system clipboard so we'll go back here we'll copy this definition we will run the copy command again go back to the client you'll notice this time it just exited rather than printing something out and inside of my client machine I'm going to open up a a neovim file again this is on the client not the devs machine and I paste and there is my function definition so effectively they are completely paired together it's forwarding directly to my clipboard on my guess machine and again as far as I'm concerned this works super super well so hope you found this interesting a little bit random but kind of a cool topic and I'll see you in the next one
Video description
Blog Post: https://joshrosso.com/c/remote-clipboard I run my development environment in portable and reproducible virtual machine built with nix. Once the VM is started, accessing all my projects is just a matter of using ssh, or mosh depending on what I’m feeling that day. The biggest, and perhaps only, pain point with my approach is clipboard sharing between client (my laptop) and server (my VM). For example, when I’m copying logs from the VM’s tmux session or copying lines in neovim, I want to have those instantly in the clipboard of my client machine. Dev Environment: 00:00:00 Dev VM Setup: 00:04:20 Client Setup: 00:10:47 Wrap up: 00:15:57