Xterm has a feature where if you put in .Xresources
XTerm.vt100.translations: #override \
Shift Ctrl<Key>V: insert-selection(CLIPBOARD)
then ctrl+shift+V will paste from clipboard.
I notice that when I paste from the clipboard with this shortcut then the pasted text will not trigger a new command and wrapped in "white background":
After some research I figure out that this is the bracketed paste mode supported by xterm. I want to make a vim key binding that does the bracketed paste into an embedded terminal in vim (opened by :ter
for example):
set termwinkey=<c-j>
" then <c-j>"+ pastes from "+ clipboard to the terminal
tnore <c-j>"+p <esc>[200~<c-j>"+<esc>[201~
This works, unless the command running inside the terminal does not support bracketed paste...
From my understanding xterm's ctrl+shift+V (if defined as above) can automatically detect whether the shell inside supports bracketed paste because the shell sends ^[[?2004h
to xterm, and if it's not seen then xterm will not send the ^[[200~
.
Question: how can the vim key binding above be defined so that it does the same thing as xterm's ctrl+shift+V?
(motivation: I want to paste from vim's @"
selection instead, while ctrl+shift+V only allows pasting from @+
)
Update: I notice that xterm has a feature to query whether bracketed paste is currently enabled...
Documentation: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
We have
CSI ? Pm h
DEC Private Mode Set (DECSET).
[...]
Ps = 2 0 0 4 ⇒ Set bracketed paste mode, xterm.
CSI ? Ps $ p
Request DEC private mode (DECRQM). For VT300 and up, reply
DECRPM is
CSI ? Ps; Pm $ y
where Ps is the mode number as in DECSET/DECSET, Pm is the
mode value as in the ANSI DECRQM.
Two private modes are read-only (i.e., 1 3 and 1 4 ),
provided only for reporting their values using this control
sequence. They correspond to the resources cursorBlink and
cursorBlinkXOR.
CSI Ps $ p
Request ANSI mode (DECRQM). For VT300 and up, reply DECRPM is
CSI Ps; Pm $ y
where Ps is the mode number as in SM/RM, and Pm is the mode
value:
0 - not recognized
1 - set
2 - reset
3 - permanently set
4 - permanently reset
In other words, if the application inside prints to the terminal ^[[?2004$p
, the terminal will return ^[[?2004;answer$y
where answer is one of {1, 2, 3, 4} as described above.
So I try doing something like this:
call writefile(["\e[?2004$p"], "/dev/tty", "b")
for s in "\e[?2004;"
if getcharstr()!=s
throw "Error"
endif
endfor
let response=getcharstr()
for s in "$y"
if getcharstr()!=s
throw "Error"
endif
endfor
echom response
it works, but always return 1 even if it's inside a terminal.
I'm not sure how TTY/PTY works unfortunately, so I don't know what to do next.
(but let's say term_gettty(bufnr())
returns /dev/pts/27
, then I can
printf '\e[?2004$p' > /dev/pts/27
to get as-if the response typed into the command running inside it, andprintf '\e]51;["call", "Tapi_log", ["123"]]\x07' > /dev/pts/27
to call vim terminal API. )
:help xterm-bracketed-paste
, and also note that you can copy the contents of the default register@"
to one of the system clipboard registers@+
,@*
to make it pasteable by the system (better: you can yank directly to such registers).@"
to@+
, I still need to "simulate" a mouse click or ctrl+shift+V etc. to make xterm paste into the vim terminal, which is suboptimal; besides, that will destroy the existing content in@+
. (xterm-bracketed-paste
only explain how vim should be configured to handle xterm properly, nothing about how to paste things from vim into embedded terminal)<C-w>""
doesn't work? Edit: ah, this probably just inserts without any bracketed-pasting…