A simple CLI for piping code to a REPL running in a separate pane
Project description
replink
replink is a CLI tool for piping code to a REPL running in a different pane.
Handy when you want to evaluate code interactively, but your favorite code editor doesn't have a plugin system (yet) but can pipe selected text to a shell command!
Demo
[video link]
Why?
replink sends code from your editor to a REPL running elsewhere.
Example: Python code to an IPython console inside a TMUX pane.
Sound easy enough? The 'sending' part may be, but getting code to show up in the right format on arrival is tricky.
As prior work like vim-slime figured out long ago, the solution lies in preprocessing code before sending it and accounting for whether the target expects bracketed paste or not. To make things extra fun, each language and each REPL presents subtle edge cases.
I built replink because I got used to sending Python code to a REPL early on in my career -- and Pycharm, VS Code, and Vim have all served to reinforce that habit. If I enjoyed maintaing a (Neo)vim config more, I would just use vim-slime or iron.nvim. But I like Helix, even if it doesn't have a plugin system. It makes up for it though with its :pipe-to command, which lets you send-and-forget selected text as stdin to any shell command -- replink, in this case. Tell replink what you're sending ('language') and where it needs to go ('target'); bind the complete command to a Helix keybinding, and you nearly have something that feels like a plugin.
Languages & Targets
replink supports these languages and targets:
Languages & REPLs:
- Python
- stock console
- Tested against various python3 REPLs.
- For python <= 3.12, use
--no-bpaste/-N. Python >= 3.13 uses bracketed paste.
- ipython
- Special --ipy-cpaste command for
%cpastepasting (I rarely need this).
- Special --ipy-cpaste command for
- ptpython
- Behaves similarly to python3.13 and above.
- stock console
Targets:
- TMUX
Adding new languages and targets is straightforward. Any language or target available in vim-slime can be ported over. This is because replink's architecture borrows heavily from vim-slime.
FRs and PRs welcome!
Install
With uv (recommended)
Use python >= 3.12.
uv tool install --python 3.12 replink
Usage
replink send -l LANGUAGE -t TARGET [OPTIONS] [TEXT/-]
Options
-l, --lang: Language (currently onlypython)-t, --target: Target configuration (e.g.,tmux:p=right,tmux:p=1)-N, --no-bpaste: Disable bracketed paste (for Python < 3.13)--ipy-cpaste: Use IPython's %cpaste command
Examples
Pipe code in
This is how I usually use replink, except I pipe in whatever is selected in my editor.
cat script.py | replink send -l python -t tmux:p=right
tmux:p=right means 'use TMUX and send to the pane on the right of the current pane'. (The value of p is anything that can be interpreted by tmux selectp -t $VALUE.)
Specifying the TMUX target using the pane number is also valid. (Hitting <prefix-key> q shows the pane numbers.)
echo 'print("well hello there")' | replink send -l python -t tmux:p=4
Code as an argument
Code can also be passed to replink as a positional argument.
replink send -l python -t tmux:p=right 'print("oh hi!")'
I only really use this when I'm debugging, since Python's built-in debugger doesn't play nice with active pipes.
However, it makes the following slightly easier to write:
replink send -l python -t tmux:p=right 'exit()'
Python < 3.13 (no bracketed paste):
Up to and including Python 3.12, the standard Python console doesn't support bracketed paste, so make sure to disable it with --no-bpaste (or -N).
cat script.py | replink send -l python -t tmux:p=right --no-bpaste
Editor Integration
Helix
Add to your ~/.config/helix/config.toml:
[keys.normal."minus"]
x = ":pipe-to replink send -l python -t tmux:p=right"
Now you can select code and press <minus>x to send it to your Python REPL. (I use minus/dash (-) as my leader for custom keybindings.)
Pro tip: If you're building Helix from master, you can specify the language dynamically by passing it in as a command line expansion. For example:
[keys.normal."minus"]
"x" = ":pipe-to replink send -l %{language} -t tmux:p=right"
Vim/Neovim
I'm not sure why you would use replink in Vim, where better options exist. But here's what Claude has to say!
" Send current line
nnoremap <leader>x :.!replink send -l python -t tmux:p=right<CR>
" Send visual selection
vnoremap <leader>x :!replink send -l python -t tmux:p=right<CR>
VS Code
Create a task in .vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "Send to REPL",
"type": "shell",
"command": "replink",
"args": ["send", "-l", "python", "-t", "tmux:p=right", "${selectedText}"]
}
]
}
Extending replink
Adding languages means implementing the Language_P protocol in replink/languages/. You handle the formatting quirks and REPL-specific behavior for your language.
Adding targets means implementing the Target_P protocol in replink/targets/. You handle the mechanics of getting text to wherever the REPL is running.
Right now there's just Python and tmux, but the design should make it straightforward to add JavaScript/Node, Ruby, R, or whatever. Same for targets like GNU Screen, Zellij, or terminal emulators with their own APIs.
Contributing
PRs welcome, especially for new languages and targets. The architecture should make this pretty straightforward.
Acknowledgments
Heavily inspired by vim-slime, which figured out all the hard parts years ago. (I've copied from this project liberally and have opted for the same license.) Also looked at iron.nvim for ideas.
License
Licensed under the MIT License. See LICENSE.txt for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file replink-0.1.0.tar.gz.
File metadata
- Download URL: replink-0.1.0.tar.gz
- Upload date:
- Size: 45.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f76193ea0bdaa5db6cefff6d127b4beaabe7f5d493e344fb8a6f38d6f664af9a
|
|
| MD5 |
505deb52772fb5ae7358b2789c635f4a
|
|
| BLAKE2b-256 |
4ff0482f93d0462b49acd1ac340955941773df4d75363b89a3b17a6f2b8b5185
|
Provenance
The following attestation bundles were made for replink-0.1.0.tar.gz:
Publisher:
publish.yml on a3lem/replink
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
replink-0.1.0.tar.gz -
Subject digest:
f76193ea0bdaa5db6cefff6d127b4beaabe7f5d493e344fb8a6f38d6f664af9a - Sigstore transparency entry: 230371286
- Sigstore integration time:
-
Permalink:
a3lem/replink@dfbeb4e19bed93a6c26599de4e0f57bb789d7645 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/a3lem
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@dfbeb4e19bed93a6c26599de4e0f57bb789d7645 -
Trigger Event:
release
-
Statement type:
File details
Details for the file replink-0.1.0-py3-none-any.whl.
File metadata
- Download URL: replink-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e9e096b35112dfdb916b8f88cad0e63a9e70f058d94f11c3e2d10a072fb97e3d
|
|
| MD5 |
b22b3c0498f142343a7456c101a4fe7e
|
|
| BLAKE2b-256 |
92dc84a0468f0b68c80fd578b685dfee17975cdb23ebc85e183db44f7e581017
|
Provenance
The following attestation bundles were made for replink-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on a3lem/replink
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
replink-0.1.0-py3-none-any.whl -
Subject digest:
e9e096b35112dfdb916b8f88cad0e63a9e70f058d94f11c3e2d10a072fb97e3d - Sigstore transparency entry: 230371290
- Sigstore integration time:
-
Permalink:
a3lem/replink@dfbeb4e19bed93a6c26599de4e0f57bb789d7645 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/a3lem
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@dfbeb4e19bed93a6c26599de4e0f57bb789d7645 -
Trigger Event:
release
-
Statement type: