|
1 | | -# RMate Server |
| 1 | +# RMate Launcher |
2 | 2 |
|
3 | | -A server implementation of the RMate protocol that allows editing remote files using a local editor of the user's choice. |
| 3 | +Seamlessly edit files over SSH with a local editor of your choice, using the rmate protocol. |
4 | 4 |
|
5 | | -## Features |
| 5 | +## Overview |
6 | 6 |
|
7 | | -- ✅ **Remote file editing** via RMate protocol |
8 | | -- ✅ **Multiple concurrent files** supported |
9 | | -- ✅ **Real-time file watching** with OS-level notifications |
10 | | -- ✅ **Cross-platform** (Linux, macOS) |
11 | | -- ✅ **Statically linked binaries** for easy deployment |
12 | | -- ✅ **Any editor** that can be launched from command line |
| 7 | +- ✅ **Remote file editing** via RMate protocol with any local editor |
| 8 | +- ✅ **Multiple concurrent files** with real-time OS-level file watching |
| 9 | +- ✅ **Cross-platform** (Linux, macOS) with statically linked binaries |
| 10 | +- ✅ **Editor agnostic** - VS Code, Sublime Text, Zed, etc. |
| 11 | +- ✅ **Always available** - Runs as standalone service, independent of editor |
13 | 12 |
|
14 | | -## Installation |
15 | | - |
16 | | -### From GitHub Releases |
| 13 | +### How it works |
17 | 14 |
|
18 | | -Download the appropriate binary for your platform from the [releases page](../../releases): |
| 15 | +1. RMate client on remote server connects via SSH tunnel to local RMate server |
| 16 | +2. Server saves file content to temp file and watches for changes with OS-level notifications |
| 17 | +3. Server spawns local editor to edit temp file |
| 18 | +4. Changes trigger `save` commands; editor close triggers `close` command |
19 | 19 |
|
20 | | -- **Linux x86_64**: `rmate_server-linux-x86_64.tar.gz` |
21 | | -- **Linux ARM64**: `rmate_server-linux-aarch64.tar.gz` |
22 | | -- **macOS Intel**: `rmate_server-macos-x86_64.tar.gz` |
23 | | -- **macOS Apple Silicon**: `rmate_server-macos-aarch64.tar.gz` |
| 20 | +### Why the rmate protocol? |
24 | 21 |
|
25 | | -```bash |
26 | | -# Download and extract (example for Linux x86_64) |
27 | | -curl -L -o rmate_server.tar.gz https://github.com/yourusername/rmate-server/releases/latest/download/rmate_server-linux-x86_64.tar.gz |
28 | | -tar -xzf rmate_server.tar.gz |
29 | | -chmod +x rmate_server-linux-x86_64 |
30 | | -mv rmate_server-linux-x86_64 /usr/local/bin/rmate_server |
31 | | -``` |
| 22 | +Originally developed for [TextMate](https://github.com/textmate/rmate), this is a proven protocol for editing remote files through SSH tunnels. It's widely supported with clients in [Ruby](https://github.com/textmate/rmate) (original), [Bash](https://github.com/aurora/rmate), [Python](https://github.com/sclukey/rmate-python), [Perl](https://github.com/davidolrik/rmate-perl), [Nim](https://github.com/aurora/rmate-nim), [C](https://github.com/hanklords/rmate.c), [Node.js](https://github.com/jrnewell/jmate), and [Go](https://github.com/mattn/gomate). Use any existing client with RMate Server - no changes required. |
32 | 23 |
|
33 | | -### From Source |
| 24 | +### Why not use existing editor extensions? |
34 | 25 |
|
35 | | -```bash |
36 | | -git clone https://github.com/yourusername/rmate-server.git |
37 | | -cd rmate-server |
38 | | -zig build -Doptimize=ReleaseSmall |
39 | | -``` |
| 26 | +Editor-specific extensions ([RemoteSubl](https://github.com/randy3k/RemoteSubl), [Remote VSCode](https://github.com/rafaelmaiolla/remote-vscode)) require the editor to be running, have inconsistent behavior, and lock you into one editor. RMate Server provides consistent functionality across all editors and future-proof remote editing. |
40 | 27 |
|
41 | | -### Running as a Service |
42 | | - |
43 | | -For production use, you may want to run rmate-server as a system service that starts automatically. |
44 | | - |
45 | | -#### macOS (launchd) |
| 28 | +## Usage |
46 | 29 |
|
47 | | -1. Copy the example plist file and customize it: |
48 | 30 | ```bash |
49 | | -cp macos-launchd.plist.example ~/Library/LaunchAgents/com.user.rmate-server.plist |
50 | | -``` |
| 31 | +# 1. Start server locally (skip this step if already running as a service) |
| 32 | +RMATE_EDITOR="code --wait" rmate_server & |
51 | 33 |
|
52 | | -2. Edit the plist file to customize: |
53 | | - - Path to your rmate_server binary |
54 | | - - Your preferred editor in `RMATE_EDITOR` |
55 | | - - Port and IP settings if different from defaults |
56 | | - - Log file paths |
| 34 | +# 2. SSH with tunnel |
| 35 | +ssh -R 52698:~/.rmate-server/rmate.sock user@remote-server |
57 | 36 |
|
58 | | -3. Load and start the service: |
59 | | -```bash |
60 | | -launchctl load ~/Library/LaunchAgents/com.user.rmate-server.plist |
61 | | -launchctl start com.user.rmate-server |
| 37 | +# 3. Edit remote files (opens in your local editor!) |
| 38 | +rmate /path/to/remote/file.txt |
62 | 39 | ``` |
63 | 40 |
|
64 | | -4. To stop or unload: |
65 | | -```bash |
66 | | -launchctl stop com.user.rmate-server |
67 | | -launchctl unload ~/Library/LaunchAgents/com.user.rmate-server.plist |
68 | | -``` |
| 41 | +### Automatic SSH Config |
69 | 42 |
|
70 | | -#### Linux (systemd) |
| 43 | +Add to `~/.ssh/config` for automatic forwarding: |
| 44 | +```ssh-config |
| 45 | +Host myserver.example.com # For specific hosts |
| 46 | + RemoteForward 52698 ~/.rmate-server/rmate.sock |
71 | 47 |
|
72 | | -1. Copy and customize the service file: |
73 | | -```bash |
74 | | -sudo cp linux-systemd.service.example /etc/systemd/system/rmate-server.service |
| 48 | +Host * # For all hosts (optional) |
| 49 | + RemoteForward 52698 ~/.rmate-server/rmate.sock |
75 | 50 | ``` |
76 | 51 |
|
77 | | -2. Edit the service file to customize: |
78 | | - - Path to your rmate_server binary |
79 | | - - Your preferred editor in `RMATE_EDITOR` |
80 | | - - Port and IP settings if different from defaults |
81 | | - |
82 | | -3. Enable and start the service: |
83 | | -```bash |
84 | | -sudo systemctl daemon-reload |
85 | | -sudo systemctl enable rmate-server |
86 | | -sudo systemctl start rmate-server |
87 | | -``` |
| 52 | +## Installation |
88 | 53 |
|
89 | | -4. Check service status: |
90 | | -```bash |
91 | | -sudo systemctl status rmate-server |
92 | | -sudo journalctl -u rmate-server -f # View logs |
93 | | -``` |
| 54 | +### From GitHub Releases |
94 | 55 |
|
95 | | -## Usage |
| 56 | +Download binaries from the [releases page](../../releases): |
| 57 | +- **Linux**: `rmate_server-linux-x86_64.tar.gz` / `rmate_server-linux-aarch64.tar.gz` |
| 58 | +- **macOS**: `rmate_server-macos-x86_64.tar.gz` / `rmate_server-macos-aarch64.tar.gz` |
96 | 59 |
|
| 60 | +```bash |
| 61 | +# Download and install (example for Linux x86_64) |
| 62 | +curl -L -o rmate_server.tar.gz https://github.com/yourusername/rmate-server/releases/latest/download/rmate_server-linux-x86_64.tar.gz |
| 63 | +tar -xzf rmate_server.tar.gz && chmod +x rmate_server-linux-x86_64 |
| 64 | +mv rmate_server-linux-x86_64 /usr/local/bin/rmate_server |
97 | 65 | ``` |
98 | | -rmate_server [OPTIONS] |
99 | | -``` |
100 | | - |
101 | | -### Options |
102 | 66 |
|
103 | | -- `--help, -h` - Show help message and exit |
104 | | - |
105 | | -### Required Environment Variables |
106 | | - |
107 | | -#### `RMATE_EDITOR` |
108 | | -Editor command to use. The command will receive the temp file path as an argument. |
| 67 | +### From Source |
109 | 68 |
|
| 69 | +Requires [Zig](https://ziglang.org/) 0.14.1+: |
110 | 70 | ```bash |
111 | | -# Examples: |
112 | | -export RMATE_EDITOR="code --wait" # VS Code |
113 | | -export RMATE_EDITOR="vim" # Vim |
114 | | -export RMATE_EDITOR="nano" # Nano |
115 | | -export RMATE_EDITOR="subl --wait" # Sublime Text |
| 71 | +git clone https://github.com/yourusername/rmate-server.git && cd rmate-server |
| 72 | +zig build -Doptimize=ReleaseSmall # or just 'zig build' for development |
116 | 73 | ``` |
117 | 74 |
|
118 | | -### Optional Environment Variables |
| 75 | +## Running as a service |
119 | 76 |
|
120 | | -#### `RMATE_PORT` |
121 | | -Port to listen on (default: 52698) |
| 77 | +For daily use, run it as a system service. Templates are provided to set up the service on macOS and Linux: |
| 78 | + |
| 79 | +#### macOS (launchd) |
122 | 80 |
|
123 | 81 | ```bash |
124 | | -export RMATE_PORT=52699 |
| 82 | +mkdir -p ~/.rmate-server |
| 83 | +cp macos-launchd.plist.example ~/Library/LaunchAgents/com.user.rmate-server.plist |
| 84 | +# Edit plist: paths, RMATE_EDITOR, RMATE_SOCKET, sandbox settings |
| 85 | +launchctl load ~/Library/LaunchAgents/com.user.rmate-server.plist |
| 86 | +launchctl start com.user.rmate-server |
125 | 87 | ``` |
126 | 88 |
|
127 | | -#### `RMATE_IP` |
128 | | -IP address to bind to (default: 127.0.0.1) |
| 89 | +#### Linux (systemd) |
129 | 90 |
|
130 | 91 | ```bash |
131 | | -export RMATE_IP=0.0.0.0 # Listen on all interfaces |
| 92 | +mkdir -p ~/.rmate-server ~/.config/systemd/user |
| 93 | +cp linux-systemd.service.example ~/.config/systemd/user/rmate-server.service |
| 94 | +# Edit service: paths, RMATE_EDITOR, RMATE_SOCKET |
| 95 | +systemctl --user daemon-reload && systemctl --user enable --now rmate-server |
| 96 | +sudo loginctl enable-linger $USER # Start on boot (optional) |
132 | 97 | ``` |
133 | 98 |
|
134 | | -## How It Works |
135 | | - |
136 | | -1. User opens remote file in SSH session using an RMate client |
137 | | -2. Client connects through SSH tunnel to RMate server running on local machine |
138 | | -3. RMate server saves file content to temporary file on disk |
139 | | -4. RMate server begins watching for changes to tempfile using OS-level file watching |
140 | | -5. RMate server spawns local editor process to edit the newly-created temporary file |
141 | | -6. On changes to the temp file, RMate server sends 'save' command to client |
142 | | -7. On close of the local editor process, RMate server sends 'close' command to client |
| 99 | +## Configuration |
143 | 100 |
|
144 | | -The server supports multiple files opened concurrently. |
| 101 | +All configuration is defined in environment variables. |
145 | 102 |
|
146 | | -## Example Setup |
147 | | - |
148 | | -### 1. Start the server locally |
| 103 | +### Required |
149 | 104 |
|
| 105 | +`RMATE_EDITOR` - Editor command to run. Path to the temp file will be passed as the first argument. |
150 | 106 | ```bash |
151 | | -RMATE_EDITOR="code --wait" rmate_server |
| 107 | +export RMATE_EDITOR="code --wait" # VS Code |
| 108 | +export RMATE_EDITOR="vim" # Vim |
| 109 | +export RMATE_EDITOR="subl --wait" # Sublime Text |
152 | 110 | ``` |
153 | 111 |
|
154 | | -### 2. Set up SSH tunnel |
| 112 | +### Optional Configuration |
155 | 113 |
|
156 | | -```bash |
157 | | -ssh -R 52698:localhost:52698 user@remote-server |
158 | | -``` |
| 114 | +- `RMATE_SOCKET` - Unix socket path (default: `~/.rmate-server/rmate.sock`) |
| 115 | +- `RMATE_PORT` / `RMATE_IP` - Legacy TCP options (default: `52698/127.0.0.1`, less secure) |
159 | 116 |
|
160 | | -### 3. Edit remote files |
| 117 | +### Advanced: Dynamic editor selection |
161 | 118 |
|
162 | | -On the remote server, use any RMate client: |
| 119 | +Since `RMATE_EDITOR` can be any command, you can use a bash script to launch different editors based on file patterns: |
163 | 120 |
|
164 | 121 | ```bash |
165 | | -# Using rmate client |
166 | | -rmate /path/to/remote/file.txt |
167 | | - |
168 | | -# The file will open in your local VS Code! |
| 122 | +#!/bin/bash |
| 123 | +# ~/.rmate-server/editor-selector.sh |
| 124 | +case "$(basename "$1")" in |
| 125 | + *.md|*.txt|README*) zed --wait "$1" ;; # Docs in Zed |
| 126 | + *.js|*.ts|*.json|*.html) code --wait "$1" ;; # Web dev in VS Code |
| 127 | + *) subl --wait "$1" ;; # Everything else in Sublime |
| 128 | +esac |
169 | 129 | ``` |
170 | | - |
171 | | -## Building from Source |
172 | | - |
173 | | -### Prerequisites |
174 | | - |
175 | | -- [Zig](https://ziglang.org/) 0.14.1 or later |
176 | | - |
177 | | -### Build Commands |
178 | | - |
179 | 130 | ```bash |
180 | | -# Development build |
181 | | -zig build |
182 | | - |
183 | | -# Optimized build |
184 | | -zig build -Doptimize=ReleaseSmall |
185 | | - |
186 | | -# Run tests |
187 | | -zig build test |
188 | | - |
189 | | -# Cross-compile for Linux |
190 | | -zig build -Dtarget=x86_64-linux-gnu -Doptimize=ReleaseSmall |
| 131 | +chmod +x ~/.rmate-server/editor-selector.sh |
| 132 | +export RMATE_EDITOR="$HOME/.rmate-server/editor-selector.sh" |
191 | 133 | ``` |
192 | 134 |
|
193 | 135 | ## Development |
194 | 136 |
|
195 | | -### Running locally |
| 137 | +### Prerequisites |
196 | 138 |
|
197 | | -```bash |
198 | | -export RMATE_EDITOR="code --wait" |
199 | | -zig build run |
200 | | -``` |
| 139 | +[Zig](https://ziglang.org/) 0.14.1+ |
201 | 140 |
|
202 | | -### Testing |
| 141 | +### Build & Run |
203 | 142 |
|
204 | 143 | ```bash |
205 | | -zig build test |
206 | | -``` |
| 144 | +zig build # Development build |
| 145 | +zig build -Doptimize=ReleaseSmall # Optimized build |
| 146 | +zig build test # Run tests |
| 147 | +zig build -Dtarget=x86_64-linux-gnu -Doptimize=ReleaseSmall # Cross-compile |
207 | 148 |
|
208 | | -## For Maintainers |
209 | | - |
210 | | -- **Release Instructions**: See [RELEASE.md](./RELEASE.md) for detailed release process |
| 149 | +# Run locally |
| 150 | +export RMATE_EDITOR="code --wait" && zig build run |
| 151 | +``` |
211 | 152 |
|
212 | 153 | ## License |
213 | 154 |
|
214 | | -[Add your license here] |
215 | | - |
216 | | -## Contributing |
217 | | - |
218 | | -[Add contributing guidelines here] |
| 155 | +MIT |
0 commit comments