Skip to content

Instantly share code, notes, and snippets.

@saitoha
Created February 6, 2013 15:43
Show Gist options
  • Select an option

  • Save saitoha/4723390 to your computer and use it in GitHub Desktop.

Select an option

Save saitoha/4723390 to your computer and use it in GitHub Desktop.
Vimと端末背景色事情 ref: http://qiita.com/kefir_/items/c2bd46728364bdc7470b
"
" This snippet is licensed under NYSL.
" See http://www.kmonos.net/nysl/NYSL.TXT
"
if !has('gui_running')
" 以下の条件を満たさない場合vim本体がbackgroundを上書きするので自前での判定はやらない
" http://yskwkzhr.blogspot.jp/2012/12/set-background-color-of-vim-with-environment-variable.html
if $TERM !~ 'linux\|screen.linux\|cygwin\|putty' && $COLORFGBG == ''
" 背景色を問い合わせるクエリ文字列を設定
" screen/tmuxではパススルーシーケンスを使用して親端末に問い合わせる
if $TMUX != ""
" tmuxを貫通させる
let s:background_teststr = "\eP\e\e]11;?\e\e\\\\\e\\"
elseif $TERM == "screen"
" GNU Screenを貫通させる
let s:background_teststr = "\eP\e]11;?\x07\e\\"
else
let s:background_teststr = "\e]11;?\e\\"
endif
" t_tiは端末がraw modeに入った直後くらいのタイミングで出力されるので、
" ここにクエリ文字列を追加
let &t_ti .= s:background_teststr
" 想定する応答の先頭9文字をmapして非同期に応答を待つ
nnoremap <special> <expr> <Esc>]11;rgb: g:SetBackground()
" MinTTYのバグ対策:OSC11ではなく、OSC0が返る
nnoremap <special> <expr> <Esc>]0;rgb: g:SetBackground()
" 端末からの応答が得られれば呼ばれる(得られない端末も多い)
function! g:SetBackground()
" mapを削除
unmap <Esc>]11;rgb:
unmap <Esc>]0;rgb:
" 追加したクエリ文字列をt_tiから取る
let &t_ti = substitute(&t_ti, s:background_teststr, '', '')
" 応答をパースして輝度を得る
let l:gamma = s:GetGammaFromRGBReport()
if l:gamma >= 0
" 境界値32768000と比較してdark/lightを判定
let l:threshold = 32768000
if l:gamma > l:threshold
set background=light
else
set background=dark
endif
endif
return ''
endfunction
" 応答の残り rrrr/gggg/bbbb ESC \ をパースして輝度を返す
" 一部 rr/gg/bb ESC \ の形式を返す端末もあるので考慮している
function! s:GetGammaFromRGBReport()
" get RGB value
let l:current = 0
let l:rgb = []
let l:count = 0
let l:failed = 0
while 1
let l:c = getchar(0)
if !l:c
break
elseif l:c == 0x7 " <Bel>
" Esc \のかわりにBELを終端とすることもできる
if l:count == 2
call add(l:rgb, l:current * 256)
elseif l:count == 4
call add(l:rgb, l:current)
else
let l:failed = 1
endif
let l:count = 0
break
elseif c == 0x1b " <Esc>
if l:count == 2
call add(l:rgb, l:current * 256)
elseif l:count == 4
call add(l:rgb, l:current)
else
let l:failed = 1
endif
let l:count = 0
" discard 1 more char
let l:c = getchar(0)
break
elseif c == 0x2f " /
if l:count == 2
call add(l:rgb, l:current * 256)
elseif l:count == 4
call add(l:rgb, l:current)
else
let l:failed = 1
endif
let l:count = 0
let l:current = 0
elseif c >= 0x30 && c < 0x40 " 0-9
let l:current = l:current * 16 + c - 0x30
let l:count += 1
elseif c >= 0x41 && c < 0x47 " A-F
let l:current = l:current * 16 + c - 0x31
let l:count += 1
elseif c >= 0x61 && c < 0x67 " a-f
let l:current = l:current * 16 + c - 0x51
let l:count += 1
endif
endwhile
if l:failed || len(l:rgb) != 3
return -1
endif
" 輝度を計算して返す
" ref: http://themergency.com/calculate-text-color-based-on-background-color-brightness/
return l:rgb[0] * 299 + l:rgb[1] * 587 + l:rgb[2] * 114
endfunction
endif
endif
ESC ] 1 1 ; ? ESC \
ESC ] 1 1 ; r g b : rrrr / gggg / bbbb ESC \
$ printf '\033]11;?\033\\'
$ printf "\033]5380;%d;bg_color\033\\" $(cat $HOME/.mlterm/challenge)
ESC ] 0 ; r g b : rrrr / gggg / bbbb ESC \
ESC ] 1 1 ; r g b : rr / gg / bb ESC \
ESC ] 1 1 ; r g b : rrrr / gggg / bbbb ESC \
"
" This snippet is licensed under NYSL.
" See http://www.kmonos.net/nysl/NYSL.TXT
"
if !has('gui_running')
function! g:SetAmbigousWidth(width)
unmap <Esc>[1;2R
unmap <Esc>[1;3R
if a:width == 1
set ambiwidth=single
elseif a:width == 2
set ambiwidth=double
endif
let &t_ti = substitute(&t_ti, s:ambiguous_teststr, '', '')
return ''
endfunction
if &term =~? 'xterm\|screen\|fbterm\|yaft\|rxvt\|jfbterm'
let s:ambiguous_teststr = "\e[1;1H\u25bd\e[6n"
endif
if exists('s:ambiguous_teststr')
nnoremap <special> <expr> <Esc>[1;2R g:SetAmbigousWidth(1)
nnoremap <special> <expr> <Esc>[1;3R g:SetAmbigousWidth(2)
" jfbtermやdvtmはゼロオリジンのCPR応答を返すバグがあるので
" (-1, -1)だけずれた位置が返る
nnoremap <special> <expr> <Esc>[0;1R g:SetAmbigousWidth(1)
nnoremap <special> <expr> <Esc>[0;2R g:SetAmbigousWidth(2)
let &t_ti .= s:ambiguous_teststr
endif
endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment