一直以来个人开发环境中linux下tmux和系统剪切板的共享功能都是通过xclip机制实现的,废话不多说直接贴在用的tmux配置文件吧:
set -g focus-events on
set -g escape-time 0
set -g mode-keys vi
set -g status-keys emacs
set -g status-interval 30
set -g display-time 1000
set -g wrap-search off
set -g base-index 1
set -g pane-base-index 1
set -g renumber-windows on
set -g automatic-rename on
set -g set-titles on
set -g set-titles-string '#W-#S'
set -g allow-rename off
set -g history-limit 81920
set -g default-terminal "xterm-256color"
set -ga terminal-overrides ",*256col*:Tc"
set -g aggressive-resize on
set -g mouse on
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi B send-keys -X rectangle-toggle \; send -X begin-selection
bind-key -T copy-mode-vi / command-prompt -p "search up" "send -X search-backward '%%%'"
bind-key -T copy-mode-vi ? command-prompt -p "search down" "send -X search-forward '%%%'"
bind-key -T copy-mode-vi WheelUpPane select-pane \; send-keys -X halfpage-up
bind-key -T copy-mode-vi WheelDownPane select-pane \; send-keys -X halfpage-down
bind-key -T copy-mode-vi y send-keys -X copy-pipe "xclip -in -sel clip"
bind-key -T copy-mode-vi MouseDown1Pane select-pane \; send-keys -X clear-selection
bind-key -T copy-mode-vi MouseDown3Pane select-pane \; send-keys -X cancel \; paste-buffer
bind-key -T copy-mode-vi MouseDragEnd1Pane select-pane \; send-keys -X copy-pipe "xclip -in -sel clip"
bind-key -T copy-mode-vi DoubleClick1Pane select-pane \; send-keys -X select-word \; send-keys -X copy-pipe "xclip -in -sel clip" \; send-keys -X select-word
bind-key -T copy-mode-vi BSpace select-pane \; send-keys -X select-word \; send-keys -X copy-pipe "xclip -in -sel clip" \; send-keys -X previous-word
bind-key -T root DoubleClick1Pane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -et=;send-keys -X select-word;send-keys -X copy-pipe \"xclip -in -sel clip\";send-keys -X select-word'"
bind-key -T root MouseDrag1Pane if-shell -F -t = "#{mouse_any_flag}" "if -Ft= '#{pane_in_mode}' 'copy-mode -et=' 'send-keys -M'" "copy-mode -et="
bind-key -T root WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -et=;send-keys -X halfpage-up'"
bind-key -T root MouseDown3Pane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'run \"xclip -o -sel clip|tmux load-buffer -\";select-pane;paste-buffer'"
unbind-key -T prefix M-m
unbind-key -T root MouseDown3Status
unbind-key -T root M-MouseDown3Pane
unbind-key -T root MouseDown3StatusLeft
bind-key -T copy-mode-vi space send-keys -X clear-selection \; send-keys -X page-up
bind-key -T copy-mode-vi Tab send-keys -X clear-selection \; send-keys -X page-down
bind-key - splitw -v
bind-key \\ splitw -h
bind-key \; selectp -R
bind-key q killp
bind-key z kill-session
bind-key b switchc -l
bind-key v switchc -t tmux-d
bind-key r source-file ~/.tmux.conf \; display "Config reloaded"
bind-key -T root M-1 selectw -t 1
bind-key -T root M-2 selectw -t 2
bind-key -T root M-3 selectw -t 3
bind-key -T root M-4 selectw -t 4
set -g status-position top
set -g window-status-separator ""
set -g status-style 'bg=colour235 fg=colour253'
set -g mode-style 'bg=colour226 fg=colour235'
set -g message-style 'fg=colour226 bg=colour235'
set -g pane-border-style 'bg=colour235 fg=colour235'
set -g pane-active-border-style 'bg=colour235 fg=colour235'
setw -g status-left ""
setw -g status-right-length "150"
setw -g status-right "#[fg=colour254,bg=colour235] %H:%M #[fg=colour235,bg=colour250] #S "
setw -g window-status-format "#[fg=colour254,bg=colour235] #I:#W "
setw -g window-status-current-format "#[fg=colour232,bg=colour163] #I:#W "
从配置可以看出关键的实现原理是通过copy-pipe "xclip -in -sel clip"这段操作实现双击拖拽等操作时自动将tmux 内部剪切板的内容复制到X window的系统剪切板中。很不幸该方法在Windows下失效了,如果想在Msys2或Git for Windows的mintty终端中使用tmux(在mintty中使用tmux的原因是默认的bash终端经常会出现vim中Alt组合键失效的问题,增加了tmux后该问题修复),则需要忍受每次复制时使用Shift作为前导键的方式才能实现复制内容到系统剪切板。昨天晚上是在无法忍受个反人类的操作方式了,于是想好好折腾一下看看有没有方法实现在MSYS环境中完成tmux和系统剪切板共享的方法。经过近2个小时的资料搜索加配置修改。最终还是实现这个小小的愿望。收集的资料和实现原理描述如下:
- Msys2(git for windows基于Msys2)环境中实现了一个/dev/clipboard驱动文件接口来完成和系统剪切板的交互, 通过echo “xxx” > /dev/clipboard即可将xxx文本复制到windows的系统剪切板中。 通过 cat /dev/clipboard也可以直接读取当前系统剪切中的内容。
- windows系统存在一个C:\Windows\System32\clip.exe程序可以实现在命令终端中将指定文件复制到系统剪切板, 操作方法为echo “xxx” | clip.exe
- 通过如下的tmux配置即可实现在Msys2中鼠标拖拽、双击等操作时自动复制内容到系统剪切板,鼠标右键自动粘贴系统剪切板的内容到终端:
bind-key -T copy-mode-vi y run "tmux save-buffer - > /dev/clipboard"
bind-key -T copy-mode-vi MouseDown1Pane select-pane \; send-keys -X clear-selection
bind-key -T copy-mode-vi MouseDown3Pane select-pane \; send-keys -X cancel \; paste-buffer
bind-key -T copy-mode-vi MouseDragEnd1Pane select-pane \; send-keys -X copy-pipe " " \; run "tmux save-buffer - > /dev/clipboard"
bind-key -T copy-mode-vi DoubleClick1Pane select-pane \; send-keys -X select-word \; send-keys -X copy-pipe " " \; send-keys -X select-word \; run "tmux save-buffer - > /dev/clipboard"
bind-key -T copy-mode-vi BSpace select-pane \; send-keys -X select-word \; send-keys -X copy-pipe " " \; run "tmux save-buffer -> /dev/clipboard" \; send-keys -X previous-word
bind-key -T root DoubleClick1Pane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -et=;send-keys -X select-word;send-keys -X copy-pipe \" \";run \"tmux save-buffer - > /dev/clipboard\";send-keys -X select-word'"
bind-key -T root MouseDrag1Pane if-shell -F -t = "#{mouse_any_flag}" "if -Ft= '#{pane_in_mode}' 'copy-mode -et=' 'send-keys -M'" "copy-mode -et="
bind-key -T root WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -et=;send-keys -X halfpage-up'"
bind-key -T root MouseDown3Pane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'run \"cat /dev/clipboard|tmux load-buffer -\";select-pane;paste-buffer'"
注意:配置中记录了复制相关存在差异的部分,其他配置保持的linux环境下一致即可。
该配置几个关键点描述如下:
- 配置中所有 ; 分割符前面的空格不可省略,否则配置无效(linux环境下也是如此),这是个非常奇葩且坑爹的语法要求,原因未知。
- 配置中除了使用run "tmux save-buffer - > /dev/clipboard"实现剪切板复制操作外,多个地方出现的 send-keys -X copy-pipe " " ;操作也不可省略(cope-pipe后双引号里的空格也不可省略),否则会出现每次复制时内容为空。
这个配置是我在不断的修改配置过程中偶然发现的可行配置方式,至于为啥要在run "tmux save-buffer - > /dev/clipboard"操作之前添加 send-keys -X copy-pipe " " ;操作也是没有搞明白。总之最后结果是这个配置工作的very nice。
折腾了2个小时终于的搞出了一个能用的东西,也算功夫没有白费。这里就贴出来给有同样需求的人的人一些帮助。(细节是魔鬼,还是让他留在地狱吧)。
|