OSC52 clipboard yanks

This commit is contained in:
Christian Nieves
2023-02-13 12:31:47 -06:00
parent 189570685b
commit 84aa6e8933
7 changed files with 117 additions and 47 deletions

49
scripts/scripts/yank Executable file
View File

@ -0,0 +1,49 @@
#!/bin/sh
#
# Usage: yank [FILE...]
#
# Copies the contents of the given files (or stdin, if no files are given) to
# the terminal that runs this program. If this program is run inside tmux(1),
# then it also copies the given contents into tmux's current clipboard buffer.
# If this program is run inside X11, then it also copies to the X11 clipboard.
#
# This is achieved by writing an OSC 52 escape sequence to the said terminal.
# The maximum length of an OSC 52 escape sequence is 100_000 bytes, of which
# 7 bytes are occupied by a "\033]52;c;" header, 1 byte by a "\a" footer, and
# 99_992 bytes by the base64-encoded result of 74_994 bytes of copyable text.
#
# In other words, this program can only copy up to 74_994 bytes of its input.
# However, in such cases, this program tries to bypass the input length limit
# by copying directly to the X11 clipboard if a $DISPLAY server is available;
# otherwise, it emits a warning (on stderr) about the number of bytes dropped.
#
# See http://en.wikipedia.org/wiki/Base64 for the 4*ceil(n/3) length formula.
# See http://sourceforge.net/p/tmux/mailman/message/32221257 for copy limits.
# See http://sourceforge.net/p/tmux/tmux-code/ci/a0295b4c2f6 for DCS in tmux.
#
# Written in 2014 by Suraj N. Kurapati <https://github.com/sunaku>
# Also documented at https://sunaku.github.io/tmux-yank-osc52.html
input=$( cat "$@" )
input() { printf %s "$input" ;}
known() { command -v "$1" >/dev/null ;}
maybe() { known "$1" && input | "$@" ;}
alive() { known "$1" && "$@" >/dev/null 2>&1 ;}
# copy to tmux
test -n "$TMUX" && maybe tmux load-buffer -
# copy via X11
test -n "$DISPLAY" && alive xhost && {
maybe xsel -i -b || maybe xclip -sel c
}
# copy via OSC 52
printf_escape() {
esc=$1
test -n "$TMUX" -o -z "${TERM##screen*}" && esc="\033Ptmux;\033$esc\033\\"
printf "$esc"
}
len=$( input | wc -c ) max=74994
test $len -gt $max && echo "$0: input is $(( len - max )) bytes too long" >&2
printf_escape "\033]52;c;$( input | head -c $max | base64 | tr -d '\r\n' )\a"

View File

@ -4,7 +4,7 @@ set-option -g update-environment "SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CO
set -g prefix C-a set -g prefix C-a
bind C-a send-prefix bind C-a send-prefix
set -g mouse on set -g mouse off
set -g prefix ` set -g prefix `
bind-key ` send-prefix bind-key ` send-prefix
@ -26,8 +26,17 @@ set -g pane-base-index 1
set-option -g base-index 1 set-option -g base-index 1
set-window-option -g pane-base-index 1 set-window-option -g pane-base-index 1
set -g default-terminal "screen-256color" # enable OSC 52 clipboard
set -ga terminal-overrides ",xterm-256color*:Tc" # tell Tmux that outside terminal supports true color set -s set-clipboard external
# tmux-256color instead of screen-256color enables italics
set -g default-terminal "tmux-256color"
# Tc enables true color
set -ag terminal-overrides ",*256col*:colors=256:Tc"
set -as terminal-features ',rxvt-unicode-256color:clipboard'
set -g allow-passthrough on
# set -g default-shell zsh # set -g default-shell zsh
# force a reload of the config file # force a reload of the config file
@ -54,7 +63,18 @@ setw -g mode-keys vi
# Setup 'v' to begin selection as in Vim # Setup 'v' to begin selection as in Vim
bind-key -Tcopy-mode-vi 'v' send -X begin-selection bind-key -Tcopy-mode-vi 'v' send -X begin-selection
bind-key -Tcopy-mode-vi 'y' send -X copy-pipe-and-cancel "xclip -sel clip -i"
# transfer copied text to attached terminal with yank
bind-key -T copy-mode-vi y send-keys -X copy-pipe 'yank > #{pane_tty}'
# transfer copied text to attached terminal with yank
bind-key -T copy-mode-vi Y send-keys -X copy-pipe 'yank > #{pane_tty}'
# transfer most-recently copied text to attached terminal with yank
bind-key -n M-y run-shell 'tmux save-buffer - | yank > #{pane_tty}'
# transfer previously copied text (chosen from a menu) to attached terminal
bind-key -n M-Y choose-buffer 'run-shell "tmux save-buffer -b \"%%%\" - | yank > #{pane_tty}"'
# Bind ']' to use pbpaste # Bind ']' to use pbpaste
#bind ] run "pbpaste | tmux load-buffer - && tmux paste-buffer" #bind ] run "pbpaste | tmux load-buffer - && tmux paste-buffer"

View File

@ -9,7 +9,7 @@ lsp_status.register_progress()
require("mason").setup() require("mason").setup()
require("mason-lspconfig").setup({ require("mason-lspconfig").setup({
ensure_installed = { "sumneko_lua", "rust_analyzer" } ensure_installed = { "lua_ls", "rust_analyzer" }
}) })
local lspconfig = require("lspconfig") local lspconfig = require("lspconfig")
@ -102,34 +102,6 @@ local runtime_path = vim.split(package.path, ";")
table.insert(runtime_path, "lua/?.lua") table.insert(runtime_path, "lua/?.lua")
table.insert(runtime_path, "lua/?/init.lua") table.insert(runtime_path, "lua/?/init.lua")
lspconfig.sumneko_lua.setup({
capabilities = capabilities,
on_attach = on_attach,
settings = {
Lua = {
runtime = {
-- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim)
version = "LuaJIT",
-- Setup your lua path
path = runtime_path,
},
diagnostics = {
-- Get the language server to recognize the `vim` global
globals = { "vim" },
},
workspace = {
-- Make the server aware of Neovim runtime files
library = vim.api.nvim_get_runtime_file("", true),
},
-- Do not send telemetry data containing a randomized but unique identifier
telemetry = {
enable = false,
},
},
},
})
local lspkind = require("lspkind") local lspkind = require("lspkind")
lspkind.init() lspkind.init()
local cmp = require("cmp") local cmp = require("cmp")

View File

@ -0,0 +1,3 @@
local map = require("utils").map
map("n", "<Leader>y", ":OSCYank<CR>", opts)
map("v", "<Leader>y", ":OSCYank<CR>", opts)

View File

@ -222,6 +222,10 @@ require('packer').startup(function(use)
'tmux-plugins/vim-tmux-focus-events', 'tmux-plugins/vim-tmux-focus-events',
'skywind3000/asyncrun.vim', 'skywind3000/asyncrun.vim',
} }
use {
'ojroques/vim-oscyank',
config = [[ require("config.oscyank") ]]
}
-- mine -- mine
use { use {

View File

@ -29,8 +29,8 @@ vmap <leader>v c<ESC>"+p<ESC>
imap <leader>v <ESC>"+pa imap <leader>v <ESC>"+pa
" Copy to OS clipboard " Copy to OS clipboard
vnoremap <leader>y "yy <Bar> :call system('xclip', @y)<CR> " vnoremap <leader>y "yy <Bar> :call system('xclip', @y)<CR>
map <leader>y "yy <Bar> :call system('xclip', @y)<CR> " map <leader>y "yy <Bar> :call system('xclip', @y)<CR>
" --------- WINDOW/PANE MAPPINGS --------- " --------- WINDOW/PANE MAPPINGS ---------
map <leader>wr <C-W>r map <leader>wr <C-W>r
@ -123,3 +123,25 @@ function! <SID>SynStack()
endfunc endfunc
nnoremap <leader>s :SaveSession<CR> nnoremap <leader>s :SaveSession<CR>
" copy to attached terminal using the yank(1) script:
" https://github.com/sunaku/home/blob/master/bin/yank
function! Yank(text) abort
let escape = system('yank', a:text)
if v:shell_error
echoerr escape
else
call writefile([escape], '/dev/tty', 'b')
endif
endfunction
noremap <silent> <Leader>y y:<C-U>call Yank(@0)<CR>
" automatically run yank(1) whenever yanking in Vim
" (this snippet was contributed by Larry Sanderson)
function! CopyYank() abort
call Yank(join(v:event.regcontents, "\n"))
endfunction
" autocmd TextYankPost * call CopyYank()
noremap <leader>y call CopyYank()
vnoremap <leader>y call CopyYank()

View File

@ -60,18 +60,18 @@ set splitbelow " Puts new split windows to the bottom of the current
set scrolljump=5 " Line to scroll when cursor leaves screen set scrolljump=5 " Line to scroll when cursor leaves screen
set scrolloff=3 " Minumum lines to keep above and below cursor set scrolloff=3 " Minumum lines to keep above and below cursor
let g:clipboard = #{ " let g:clipboard = #{
\ name: 'xsel', " \ name: 'xsel',
\ copy: { " \ copy: {
\ '+': ['xclip', '--nodetach', '-i', '-b'], " \ '+': ['xclip', '--nodetach', '-i', '-b'],
\ '*': ['xclip', '--nodetach', '-i', '-p'], " \ '*': ['xclip', '--nodetach', '-i', '-p'],
\ }, " \ },
\ paste: { " \ paste: {
\ '+': ['xclip', '-o', '-b'], " \ '+': ['xclip', '-o', '-b'],
\ '*': ['xclip', '-o', '-p'], " \ '*': ['xclip', '-o', '-p'],
\ }, " \ },
\ cache_enabled: 1, " \ cache_enabled: 1,
\ } " \ }
set shortmess=A set shortmess=A
set shortmess+=O set shortmess+=O
set modifiable set modifiable