Update connectivity diagnostics zip.
[chromiumos/platform/assets.git] / chromeapps / hterm / etc / osc52.vim
1 " Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 " Use of this source code is governed by a BSD-style license that can be
3 " found in the LICENSE file.
4
5 "
6 " This script can be used to send an arbitrary string to the terminal clipboard
7 " using the OSC 52 escape sequence, as specified in
8 " http://invisible-island.net/xterm/ctlseqs/ctlseqs.html, section "Operating
9 " System Controls", Ps => 52.
10 "
11 " To add this script to vim...
12 "  1. Save it somewhere.
13 "  2. Edit ~/.vimrc to include...
14 "       source ~/path/to/osc52.vim
15 "       vmap <C-c> y:call SendViaOSC52(getreg('"'))<cr>
16 "
17 " This will map Ctrl-C to copy.  You can now select text in vi using the visual
18 " mark mode or the mouse, and press Ctrl-C to copy it to the clipboard.
19 "
20
21 " Max length of the OSC 52 sequence.  Sequences longer than this will not be
22 " sent to the terminal.
23 let g:max_osc52_sequence=100000
24
25 " Send a string to the terminal's clipboard using the OSC 52 sequence.
26 function! SendViaOSC52 (str)
27   if match($TERM, 'screen') > -1
28     let osc52 = s:get_OSC52_DCS(a:str)
29   else
30     let osc52 = s:get_OSC52(a:str)
31   endif
32
33   let len = strlen(osc52)
34   if len < g:max_osc52_sequence
35     call s:rawecho(osc52)
36   else
37     echo "Selection too long to send to terminal: " . len
38   endif
39 endfunction
40
41 " This function base64's the entire string and wraps it in a single OSC52.
42 "
43 " It's appropriate when running in a raw terminal that supports OSC 52.
44 function! s:get_OSC52 (str)
45   let b64 = s:b64encode(a:str)
46   let rv = "\e]52;c;" . b64 . "\x07"
47   return rv
48 endfunction
49
50 " This function base64's the entire source, wraps it in a single OSC52, and then
51 " breaks the result in small chunks which are each wrapped in a DCS sequence.
52 "
53 " This is appropriate when running on `screen`.  Screen doesn't support OSC 52,
54 " but will pass the contents of a DCS sequence to the outer terminal unmolested.
55 " It imposes a small max length to DCS sequences, so we send in chunks.
56 function! s:get_OSC52_DCS (str)
57   " The base64 commands with no params will return a string with newlines
58   " every 72 characters.
59   let b64 = s:b64encode(a:str)
60
61   " Remove the trailing newline.
62   let b64 = substitute(b64, '\n*$', '', '')
63
64   " Replace each newline with an <end-dcs><start-dcs> pair.
65   let b64 = substitute(b64, '\n', "\e/\eP", "g")
66
67   " (except end-of-dcs is "ESC \", begin is "ESC P", and I can't figure out
68   "  how to express "ESC \ ESC P" in a single string.  So, the first substitute
69   "  uses "ESC / ESC P", and the second one swaps out the "/".  It seems like
70   "  there should be a better way.)
71   let b64 = substitute(b64, '/', '\', 'g')
72
73   " Now wrap the whole thing in <start-dcs><start-osc52>...<end-osc52><end-dcs>.
74   let b64 = "\eP\e]52;c;" . b64 . "\x07\e\x5c"
75
76   return b64
77 endfunction
78
79 " Echo a string to the terminal without munging the escape sequences.
80 "
81 " This function causes the terminal to flash as a side effect.  It would be
82 " better if it didn't, but I can't figure out how.
83 function! s:rawecho (str)
84   exec("silent! !echo " . shellescape(a:str))
85   redraw!
86 endfunction
87
88 " Lookup table for s:b64encode.
89 let s:b64_table = [
90       \ "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P",
91       \ "Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f",
92       \ "g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v",
93       \ "w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"]
94
95 " Encode a string of bytes in base 64.
96 " Copied from http://vim-soko.googlecode.com/svn-history/r405/trunk/vimfiles/
97 " autoload/base64.vim
98 function! s:b64encode(str)
99   let bytes = s:str2bytes(a:str)
100   let b64 = []
101
102   for i in range(0, len(bytes) - 1, 3)
103     let n = bytes[i] * 0x10000
104           \ + get(bytes, i + 1, 0) * 0x100
105           \ + get(bytes, i + 2, 0)
106     call add(b64, s:b64_table[n / 0x40000])
107     call add(b64, s:b64_table[n / 0x1000 % 0x40])
108     call add(b64, s:b64_table[n / 0x40 % 0x40])
109     call add(b64, s:b64_table[n % 0x40])
110   endfor
111
112   if len(bytes) % 3 == 1
113     let b64[-1] = '='
114     let b64[-2] = '='
115   endif
116
117   if len(bytes) % 3 == 2
118     let b64[-1] = '='
119   endif
120
121   return join(b64, '')
122
123 endfunction
124
125 function! s:str2bytes(str)
126   return map(range(len(a:str)), 'char2nr(a:str[v:val])')
127 endfunction