Skip to content

Commit 10b024f

Browse files
committed
Use socket instead of port, update README
1 parent 2e119ea commit 10b024f

File tree

6 files changed

+246
-193
lines changed

6 files changed

+246
-193
lines changed

README.md

Lines changed: 92 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,218 +1,155 @@
1-
# RMate Server
1+
# RMate Launcher
22

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.
44

5-
## Features
5+
## Overview
66

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
1312

14-
## Installation
15-
16-
### From GitHub Releases
13+
### How it works
1714

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
1919

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?
2421

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.
3223

33-
### From Source
24+
### Why not use existing editor extensions?
3425

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.
4027

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
4629

47-
1. Copy the example plist file and customize it:
4830
```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 &
5133

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
5736

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
6239
```
6340

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
6942

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
7147
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
7550
```
7651

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
8853

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
9455

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`
9659

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
9765
```
98-
rmate_server [OPTIONS]
99-
```
100-
101-
### Options
10266

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
10968

69+
Requires [Zig](https://ziglang.org/) 0.14.1+:
11070
```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
11673
```
11774

118-
### Optional Environment Variables
75+
## Running as a service
11976

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)
12280

12381
```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
12587
```
12688

127-
#### `RMATE_IP`
128-
IP address to bind to (default: 127.0.0.1)
89+
#### Linux (systemd)
12990

13091
```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)
13297
```
13398

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
143100

144-
The server supports multiple files opened concurrently.
101+
All configuration is defined in environment variables.
145102

146-
## Example Setup
147-
148-
### 1. Start the server locally
103+
### Required
149104

105+
`RMATE_EDITOR` - Editor command to run. Path to the temp file will be passed as the first argument.
150106
```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
152110
```
153111

154-
### 2. Set up SSH tunnel
112+
### Optional Configuration
155113

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)
159116

160-
### 3. Edit remote files
117+
### Advanced: Dynamic editor selection
161118

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:
163120

164121
```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
169129
```
170-
171-
## Building from Source
172-
173-
### Prerequisites
174-
175-
- [Zig](https://ziglang.org/) 0.14.1 or later
176-
177-
### Build Commands
178-
179130
```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"
191133
```
192134

193135
## Development
194136

195-
### Running locally
137+
### Prerequisites
196138

197-
```bash
198-
export RMATE_EDITOR="code --wait"
199-
zig build run
200-
```
139+
[Zig](https://ziglang.org/) 0.14.1+
201140

202-
### Testing
141+
### Build & Run
203142

204143
```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
207148

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+
```
211152

212153
## License
213154

214-
[Add your license here]
215-
216-
## Contributing
217-
218-
[Add contributing guidelines here]
155+
MIT

linux-systemd.service.example

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@ Type=simple
88
ExecStart=/usr/local/bin/rmate_server
99
Restart=always
1010
RestartSec=5
11-
DynamicUser=true
1211

1312
# Environment variables
1413
Environment=RMATE_EDITOR=code --wait
15-
Environment=RMATE_PORT=52698
16-
Environment=RMATE_IP=127.0.0.1
14+
# RMATE_SOCKET defaults to %h/.rmate-server/rmate.sock if not specified
15+
# Environment=RMATE_SOCKET=%h/.rmate-server/rmate.sock
1716

1817
# Logging
1918
StandardOutput=journal
@@ -22,10 +21,14 @@ SyslogIdentifier=rmate-server
2221

2322
# Security settings
2423
NoNewPrivileges=true
25-
PrivateTmp=true
2624
ProtectSystem=strict
27-
ProtectHome=true
28-
ReadWritePaths=/tmp
25+
ProtectHome=tmpfs
26+
ReadWritePaths=%h/.rmate-server
27+
ReadOnlyPaths=%h/.config %h/.local
28+
PrivateDevices=true
29+
ProtectKernelTunables=true
30+
ProtectKernelModules=true
31+
ProtectControlGroups=true
2932

3033
[Install]
31-
WantedBy=multi-user.target
34+
WantedBy=default.target

macos-launchd.plist.example

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414
<dict>
1515
<key>RMATE_EDITOR</key>
1616
<string>code --wait</string>
17-
<key>RMATE_PORT</key>
18-
<string>52698</string>
19-
<key>RMATE_IP</key>
20-
<string>127.0.0.1</string>
17+
<!-- RMATE_SOCKET defaults to ~/.rmate-server/rmate.sock if not specified -->
18+
<!--
19+
<key>RMATE_SOCKET</key>
20+
<string>/Users/USERNAME/.rmate-server/rmate.sock</string>
21+
-->
2122
</dict>
2223

2324
<key>RunAtLoad</key>
@@ -33,6 +34,23 @@
3334
<string>/usr/local/var/log/rmate-server-error.log</string>
3435

3536
<key>WorkingDirectory</key>
36-
<string>/tmp</string>
37+
<string>/Users/USERNAME/.rmate-server</string>
38+
39+
<!-- Note: Update USERNAME above to your actual username -->
40+
41+
<!-- Uncomment the sandbox profile below for additional security -->
42+
<!--
43+
<key>SandboxProfile</key>
44+
<string>
45+
(version 1)
46+
(deny default)
47+
(allow process-exec (literal "/usr/local/bin/rmate_server"))
48+
(allow file-read* file-write* (subpath "/Users/USERNAME/.rmate-server"))
49+
(allow file-read* (subpath "/usr/bin") (subpath "/usr/local/bin"))
50+
(allow file-read* (subpath "/Applications"))
51+
(allow network-outbound (remote ip))
52+
(allow network-bind (local ip))
53+
</string>
54+
-->
3755
</dict>
3856
</plist>

0 commit comments

Comments
 (0)