clipse
is a highly configurable, TUI-based clipboard manager application written in Go with minimal dependency. Though the app is optimised for a linux OS using a dedicated window manager, clipse
can also be used on any Unix-based system. Simply install the package and bind the open command to get your desired clipboard behavior. Further instructions for setting this up can be found below.
Click here to see a video demo for clipse
This requires a standard system clipboard like one of the following:
- wl-clipboard
- xclip
- xsel
- termux-clipboard
Does not require any additional dependency.
Does not require any additional dependency.
A customisable TUI allows you to easily match your system's theme. The app is based on your terminal's theme by default but is editable from a .config/clipse/custom_theme.json
file that gets created when the program is run for the first time. Some example themes (based on my terminal)...
Nord
Dracula
Gruvbox
An example .config/clipse/custom_theme.json
:
{
"useCustomTheme": true,
"DimmedDesc": "#4C566A",
"DimmedTitle": "#4C566A",
"FilteredMatch": "#A3BE8C",
"NormalDesc": "#81A1C1",
"NormalTitle": "#B48EAD",
"SelectedDesc": "#A3BE8C",
"SelectedTitle": "#A3BE8C",
"SelectedBorder": "#88C0D0",
"SelectedDescBorder": "#88C0D0",
"TitleFore": "#D8DEE9",
"Titleback": "#3B4252",
"StatusMsg": "#8FBCBB"
}
Simply leaving this file alone or setting the useCustomTheme
value to false
will give you a nice default theme...
Easily recall, add, and delete clipboard history via a smooth TUI experience built with Go's excellent BubbleTea library. A simple fuzzy finder, callable with the /
key can easily match content from a theoretically unlimited amount of time in the past:
Items can be permanently deleted from the list by simply hitting backspace
when the item is selected, as seen in the demo video, and can be added explicitly from the command line using the -a
flag. This would allow you to easily pipe any CLI output directly into your history with commands like:
ls /home | clipse -a
clipse -a "a custom string value"
Due to Go's inbuilt garbage collection system and the way the application is built, clipse
is pretty selfless when it comes to CPU consumption and memory. The below image shows how little resources are required to run the background event listener used to continually update the history displayed in the TUI...
The clipse
binary, installable from the repo, can run on pretty much any Unix-based OS, though currently optimized for linux. Being terminal-based also allows for easy integration with a window manager and configuration of how the TUI behaves. For example, binding a floating window to the clipse
command as shown in my example using Hyprland window manager on NixOs.
Note that working with image files will require one of the following dependencies to be installd on your system:
- Linux (X11) & MacOs: xclip
- Linux (Wayland): wl-clipboard
See below for instructions on getting clipse installed and configured effectively.
As a new package, clipse
is still currently on the Unstable
branch of nixpkgs
. You can use the following methods to install...
Direct install (recommended)
nix-env -f channel:nixpkgs-unstable -iA clipse
Nix shell
nix shell github:NixOS/nixpkgs#clipse
System package
Building unstable clipse
as a system package may depend on your nix environemnt. I would suggest referencing this article for best practice. The derivation can also be built from source using the following:
{ lib
, buildGoModule
, fetchFromGitHub
}:
buildGoModule rec {
pname = "clipse";
version = "0.0.6";
src = fetchFromGitHub {
owner = "savedra1";
repo = "clipse";
rev = "v${version}";
hash = "sha256-DLvYTPlLkp98zCzmbeL68B7mHl7RY3ee9rL30vYm5Ow=";
};
vendorHash = "sha256-GIUEx4h3xvLySjBAQKajby2cdH8ioHkv8aPskHN0V+w=";
meta = {
description = "Useful clipboard manager TUI for Unix";
homepage = "https://github.com/savedra1/clipse";
license = lib.licenses.mit;
mainProgram = "clipse";
maintainers = [ lib.maintainers.savedra1 ];
};
}
The AUR package can be found here
Installing with yay
yay -S example-package
Installing from pkg source
git clone https://aur.archlinux.org/clipse.git && cd clipse && makepkg -si
Linux arm64:
wget -c https://github.com/savedra1/clipse/releases/download/v0.0.6/clipse_0.0.6_linux_arm64.tar.gz -O - | tar -xz
Linux amd64:
wget -c https://github.com/savedra1/clipse/releases/download/v0.0.6/clipse_0.0.6_linux_amd64.tar.gz -O - | tar -xz
Linux 836:
wget -c https://github.com/savedra1/clipse/releases/download/v0.0.6/clipse_0.0.6_linux_836.tar.gz -O - | tar -xz
Darwin arm64:
wget -c https://github.com/savedra1/clipse/releases/download/v0.0.6/clipse_0.0.6_darwin_arm64.tar.gz -O - | tar -xz
Darwin amd64:
wget -c https://github.com/savedra1/clipse/releases/download/v0.0.6/clipse_0.0.6_darwin_amd64.tar.gz -O - | tar -xz
go install github.com/savedra1/[email protected]
git clone https://github.com/savedra1/clipse
cd clipse
go mod tidy
go build -o clipse
As mentioned earlier, to get the most out of clipse
you'll want to bind the two key commands to your systems config. The first key command is to open the clipboard history TUI:
clipse $PPID
Passing in the $PPID
variable as an arg to the main command ensures the TUI will close the terminal session in which it's hosted on the choose
event, despite the environment in which it's called. Without passing in $PPID
, your TUI selection will enter persistent mode where the window will not close automatically after selection. The $PPID
var is also not available in every terminal environment. If you find the program enters persistent mode even when passing this in you will need to find the correct var to use instead. EG, $fish_pid
.
The second command doesn't need to be bound to a key combination, but rather to the system boot to run the background listener on start-up:
clipse -listen
The above command creates a nohup
process of clipse --listen-shell
, which if called on its own will start a listener in your current terminal session instead. If nohup
is not supported on your system, you can use your preferred method of running clipse --listen-shell
in the background instead.
Note: The following examples are based on bash/zsh shell environments. If you use something else like foot
or fish
, you may need to construct the command differently, referencing the relevant documentation.
Add the following lines to your Hyprland config file:
exec-once = clipse -listen # run listener on startup
windowrulev2 = float,class:(floating) # ensure you have defined a floating window class
bind = SUPER, V, exec, <terminal name> --class floating -e <shell-env> -c 'clipse $PPID' # bind the open clipboard operation to a nice key.
# Example: bind = SUPER, V, exec, alacritty --class floating -e zsh -c 'clipse $PPID'
Add the following commands to your .config/i3/config
file:
exec --no-startup-id clipse -listen # run listener on startup
bindsym $mod+V exec --no-startup-id urxvt -e "$SHELL" -c "i3-msg 'floating enable' && clipse $PPID" # Bind floating shell with TUI selection to something nice
Add the following config to your ~/.config/sway/config
file:
exec clipse -listen # run the background listener on startup
bindsym $mod+V exec <terminal name> -e sh -c "swaymsg floating enable, move position center; swaymsg resize set 80ppt 80ppt && clipse $PPID" # Bind floating shell with TUI selection to something nice
Every system/window manager is different and hard to determine exactly how to achieve the more βGUI-likeβ behaviour. If using something not mentioned above, just refer to your systems documentation to find how to:
- Run the
clipse -listen
/clipse --listen-shell
command on startup - Bind the
clipse $PPID
command to a key that opens a terminal session (ideally in a window)
clipse
is more than just a TUI. It also offers a number of CLI commands for managing clipboard content directly from the terminal.
# Operational commands
clipse -a <arg> # Adds <arg> directly to the clipboard history without copying to system clipboard (string
clipse -a # Adds any standard input directly to the clipboard history without copying to the system clipboard.
# For example: echo "some data" | clipse -a
clipse -c <arg> # Copy the <arg> to the system clipboard (string). This also adds to clipboard history if currently listening.
clipse -c # Copies any standard input directly to the system clipboard.
# For example: echo "some data" | clipse -c
clipse -p # Prints the current clipboard content to the console.
# Example: clipse -p > file.txt
# TUI management commands
clipse $PPID # Open Clipboard TUI
clipse -listen # Run a background listener process
clipse --listen-shell # Run a listener process in the current terminal
clipse -help # Display menu option
clipse -v # Get version
clipse -clear # Wipe all clipboard history and current system clipboard value
clipse -kill # Kill any existing background processes
clipse # Open Clipboard TUI in persistent/debug mode
You can view the full list of key bind commands when in the TUI by hitting the ?
key:
When the app is run for the first time it creates a /home/$USER/.config/clipse
dir with a clipboard_hostory.json
file, a custom_theme.json
file, and tmp_files
folder for storing image data. After the clipse -listen
command is executed, a background process will be watching for clipboard activity and adding any changes to the clipboard_hstory.json
file.
The TUI that displays the clipboard history should then be called with the clipse $PPID
command. Passing in the terminal's PPID is irregular, but allows the terminal-based app to close itself from within the program itself, simulating the behavior of a full GUI without the memory overhead. A worthy trade-off in my opinion.
Operations within the TUI are defined with the BubbleTea framework, allowing for efficient concurrency and a smooth UX. Delete
operations will remove the selected item from the TUI view and the storage file, select
operations will copy the item to the systems clipboard and close the terminal window in which the session is currently hosted.
The maximum item storage limit is currently hardcoded at 100. However, there are plans to make this configurable in the future.
I would love to receive contributions to this project and welcome PRs from anyone and everyone. The following is a list of example future enhancements I'd like to implement:
- Image previews in TUI view rather than
<BINARY FILE>
- Customisable max history limit
- System paste option (building functionality to paste the chosen item directly into the next place of focus after the TUI closes)
- Packages for apt, dnf, brew etc
- Theme adjustments made available via CLI
- Better debugging
- Use of a GUI library such as fyne/GIO (only with minimal CPU cost)
- Custom key binds added to config file
- Customisable config file storage paths
-
My terminal window does not close on selection, even when using
clipse $PPID
- Some terminal environments reference system variables differently. For example, the fish terminal will need to use$fish_pid
instead. To debug this error you can runecho $PPID
to see what gets returned. The 'close on selection functionality is also not currently available for MacOs as killing the terminals ppid does not close the window - it seems applescript is needed to achieve this. -
Why is it necessary to pass in the
$PPID
arg? - Although your WM setup may close the window on process completion anyway, this is passed in to maintain consistent behaviour across all WMs and shell environments to ensure the window session can be always be killed. More elegant solutions to this are welcomed as PRs. -
Is there risk of multiple parallel processes running? - No. The
clipse
command kills any existing TUI processes before opening up and theclipse -listen
command kills any existing background listeners before starting a new one.
- [bug] Tmp image files not deleting on some machines
- Extra Config file for item limit, keybinds and clise dir
- Solution for auto-closing terminal window on MacOs
- image preview
- integrating xclip+wl-clip into binary with gcc