Recently I switched to the Sway window manager on my favorite laptop and realized that ClipIt does not work there. I was reminded of an old Ruby script I wrote way back in 2012 to serve this purpose.

Time to dust that thing off and make it work with Wayland! I installed the excellent wl-clipboard by Sergey Bugaev and started hacking.

Here is my script:

#!/usr/bin/env ruby # https://mpov.timmorgan.org/clipboard-history-in-sway-window-manager/ require 'json' STORE = "#{ENV['HOME']}/.clipboard-history" LIMIT = 100 unless File.exist?(STORE) File.open(STORE, 'w') { |f| f.write('[]') } end puts 'read clips' clips = JSON.load(File.read(STORE)) if ARGV[0] == 'menu' puts 'show menu' sel = nil IO.popen("dmenu -p 'select a paste'", 'r+') do |io| io.write(clips.map(&:to_json).join("

")) io.close_write sel = io.read end exit if sel.empty? IO.popen('wl-copy --type text/plain', 'w') { |io| io.write(JSON.parse(sel)) } else loop do clip = `wl-paste -n` if !clip.strip.empty? && clip != clips.first puts 'add clip' clips = ([clip] + clips).uniq[0...LIMIT] File.open(STORE, 'w') do |file| file.puts(JSON.pretty_generate(clips)) end end sleep 5 end end

Here’s how to use it:

Save the script above to a file at /usr/local/bin/clipd and make it executable. Install dmenu if you don’t already have it. Install wl-clipboard from source. At the time of this writing, the package in the Ubuntu repository is fairly old and causes some screen glitching. The latest version on GitHub fixed that for me. Add the following config to your Sway config at ~/.config/sway/config : bindsym $mod+v exec clipd menu exec --no-startup-id clipd Restart Sway.

Now, when you copy text, clipd will see the new text (within 5 seconds) and add it to your ~/.clipboard-history file. It keeps the last 100 entries there.

When you press Mod + v, a menu will show the entries and allow you to make a selection. The item you select will be put back on the clipboard so you can paste it.

Enjoy!