tmux: fold tmux-copy into tmux-grab
The whitespace-token pass in tmux-grab already captures whole URLs as
candidates, so the only missing piece was an open action. Add ctrl-o
alongside enter (insert) and ctrl-y (copy), then retire tmux-copy and
its C-y binding now that tmux-grab covers all three actions.

Assisted-by: Claude Sonnet 5 via Claude Code
change oonwupwmkmwvuwuovxkuxywmxpooyryv
commit 989d80ac5509582693ff0a8260c23fd1e47f4ea9
author Alpha Chen <alpha@kejadlen.dev>
date
parent lvtyyrrw
diff --git a/.config/tmux/tmux.conf b/.config/tmux/tmux.conf
index a0d6ac6a..d2ad5c53 100644
--- a/.config/tmux/tmux.conf
+++ b/.config/tmux/tmux.conf
@@ -101,7 +101,6 @@ bind Tab new-pane -x 80% -y 60% -X 10% -Y 20% -e IN_TMUX_FLOAT=1 -- "~/.dotfiles
 # bind -Tfzf-git C-h send-keys C-g h
 # bind -Troot C-g switch-client -Tfzf-git
 
-bind C-y run -b ~/.dotfiles/bin/,tmux-copy
 bind r source-file ~/.config/tmux/tmux.conf \; display-message "tmux.conf reloaded"
 
 if-shell "[[ -e ~/.config/tmux/tmux.conf.local ]]" "source-file ~/.config/tmux/tmux.conf.local"
diff --git a/bin/,tmux-copy b/bin/,tmux-copy
deleted file mode 100755
index 701824da..00000000
--- a/bin/,tmux-copy
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env ruby
-# frozen_string_literal: true
-
-# https://github.com/junegunn/tmux-fzf-url
-
-require 'English'
-require 'shellwords'
-
-def executable(*commands)
-  commands.find do |c|
-    `command -v #{c.split.first}`.empty?.!
-  end
-end
-
-def halt(message)
-  system "tmux display-message #{Shellwords.escape(message)}"
-  exit
-end
-
-def with(command)
-  io = IO.popen(command, 'r+')
-  begin
-    stdout = $stdout
-    $stdout = io
-    begin
-      yield
-    rescue Errno::EPIPE
-      nil
-    end
-  ensure
-    $stdout = stdout
-  end
-  io.close_write
-  io.readlines.map(&:chomp)
-end
-
-# TODO: Keep it simple for now
-def extract_urls(line)
-  line.scan(%r{(?:https?|file)://[-a-zA-Z0-9@:%_+.~#?&/=]+[-a-zA-Z0-9@%_+.~#?&/=!]+}x)
-end
-
-lines = `tmux capture-pane -J -p -S -99999`
-urls = lines.each_line.map(&:strip).reject(&:empty?)
-            .flat_map { |l| extract_urls(l) }.reverse.uniq
-halt 'No URLs found' if urls.empty?
-
-header = 'Press CTRL-Y to copy URL to clipboard'
-max_size = `tmux display-message -p "\#{client_width} \#{client_height}"`.split.map(&:to_i)
-size = [[*urls, header].map(&:length).max + 7, urls.length + 5].zip(max_size).map(&:min).join(',')
-opts = ['--tmux', size, '--multi', '--no-margin', '--no-padding', '--wrap',
-        '--expect', 'ctrl-y',
-        '--header', header,
-        '--highlight-line', '--header-first', '--info', 'inline-right',
-        '--border-label', ' URLs '].map(&:shellescape).join(' ')
-selected = with("fzf #{opts}") do
-  puts urls
-end
-exit if selected.length < 2
-
-if selected.first == 'ctrl-y'
-  # https://superuser.com/questions/288320/whats-like-osxs-pbcopy-for-linux
-  copier = executable('reattach-to-user-namespace pbcopy',
-                      'pbcopy',
-                      'xsel --clipboard --input',
-                      'xclip -selection clipboard')
-  halt 'No command to control clipboard with' unless copier
-  with(copier) do
-    print selected.drop(1).join($RS).strip
-  end
-  halt 'Copied to clipboard'
-end
-
-opener = executable('open', 'xdg-open')
-opener = 'nohup xdg-open' if opener == 'xdg-open'
-halt 'No command to open URL with' unless opener
-selected.drop(1).each do |url|
-  system "#{opener} #{Shellwords.escape(url)} &> /dev/null"
-end
diff --git a/bin/,tmux-grab b/bin/,tmux-grab
index ca3abfa0..5deb8fd3 100755
--- a/bin/,tmux-grab
+++ b/bin/,tmux-grab
@@ -38,8 +38,8 @@ main() {
     local tmux_opts=(--tmux "80%,60%")
     [[ -n "${IN_TMUX_FLOAT:-}" ]] && tmux_opts=()
 
-    # --expect ctrl-y reports which key completed the selection: it's the
-    # first line of output, empty unless ctrl-y was the trigger, with the
+    # --expect reports which key completed the selection: it's the first
+    # line of output, empty unless ctrl-y/ctrl-o was the trigger, with the
     # selected token on the following line.
     local result
     result=$(printf '%s\n' "$tokens" | FZF_DEFAULT_OPTS='' fzf --no-multi --select-1 --no-margin --no-padding \
@@ -47,8 +47,8 @@ main() {
         --layout reverse \
         --height 100% \
         --highlight-line --info inline-right \
-        --header 'enter: insert  ctrl-y: copy' --header-first \
-        --expect ctrl-y \
+        --header 'enter: insert  ctrl-y: copy  ctrl-o: open' --header-first \
+        --expect ctrl-y,ctrl-o \
         --border-label ' grab ') || exit 0
     [[ -n "$result" ]] || exit 0
 
@@ -57,12 +57,18 @@ main() {
     selection=$(tail -n +2 <<<"$result")
     [[ -n "$selection" ]] || exit 0
 
-    if [[ "$key" == "ctrl-y" ]]; then
-        printf '%s' "$selection" | pbcopy
-        tmux display-message 'Copied to clipboard'
-    else
-        tmux send-keys -l -t "$pane_id" -- "$selection"
-    fi
+    case "$key" in
+        ctrl-y)
+            printf '%s' "$selection" | pbcopy
+            tmux display-message 'Copied to clipboard'
+            ;;
+        ctrl-o)
+            open -- "$selection"
+            ;;
+        *)
+            tmux send-keys -l -t "$pane_id" -- "$selection"
+            ;;
+    esac
 }
 
 main "$@"