Skip to content

Commit 04bfa81

Browse files
committed
[Colors] Change color scheme on the fly (experimental)
1 parent 6f28c8c commit 04bfa81

File tree

2 files changed

+129
-4
lines changed

2 files changed

+129
-4
lines changed

autoload/fzf/vim.vim

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -578,16 +578,46 @@ endfunction
578578
" ------------------------------------------------------------------
579579
" Colors
580580
" ------------------------------------------------------------------
581+
function! s:colors_exit(code)
582+
if exists('s:colors_name')
583+
if a:code > 0 && s:colors_name != g:colors_name
584+
execute 'colo' s:colors_name
585+
endif
586+
unlet s:colors_name
587+
endif
588+
call fzf#vim#ipc#stop()
589+
endfunction
590+
581591
function! fzf#vim#colors(...)
582592
let colors = split(globpath(&rtp, "colors/*.vim"), "\n")
583593
if has('packages')
584594
let colors += split(globpath(&packpath, "pack/*/opt/*/colors/*.vim"), "\n")
585595
endif
586-
return s:fzf('colors', {
587-
\ 'source': fzf#vim#_uniq(map(colors, "substitute(fnamemodify(v:val, ':t'), '\\..\\{-}$', '', '')")),
596+
let colors = fzf#vim#_uniq(map(colors, "fnamemodify(v:val, ':t')[:-5]"))
597+
598+
" Put the current colorscheme at the top
599+
if exists('g:colors_name')
600+
let s:colors_name = g:colors_name
601+
let colors = [g:colors_name] + filter(colors, 'g:colors_name != v:val')
602+
endif
603+
604+
let spec = {
605+
\ 'source': colors,
588606
\ 'sink': 'colo',
589-
\ 'options': '+m --prompt="Colors> "'
590-
\}, a:000)
607+
\ 'options': ['+m', '--prompt', 'Colors> ']
608+
\}
609+
610+
if !a:1 " We can't set up IPC in fullscreen mode in Vim
611+
let fifo = fzf#vim#ipc#start({ msg -> execute('colo '.msg) })
612+
if len(fifo)
613+
call extend(spec.options, ['--no-tmux', '--no-padding', '--no-margin', '--bind', 'focus:execute-silent:echo {} > '.fifo])
614+
let spec.exit = s:function('s:colors_exit')
615+
let maxwidth = max(map(copy(colors), 'strwidth(v:val)'))
616+
let spec.window = { 'width': maxwidth + 8, 'height': len(colors) + 5 }
617+
endif
618+
endif
619+
620+
call s:fzf('colors', spec, a:000)
591621
endfunction
592622

593623
" ------------------------------------------------------------------

autoload/fzf/vim/ipc.vim

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
" Copyright (c) 2024 Junegunn Choi
2+
"
3+
" MIT License
4+
"
5+
" Permission is hereby granted, free of charge, to any person obtaining
6+
" a copy of this software and associated documentation files (the
7+
" "Software"), to deal in the Software without restriction, including
8+
" without limitation the rights to use, copy, modify, merge, publish,
9+
" distribute, sublicense, and/or sell copies of the Software, and to
10+
" permit persons to whom the Software is furnished to do so, subject to
11+
" the following conditions:
12+
"
13+
" The above copyright notice and this permission notice shall be
14+
" included in all copies or substantial portions of the Software.
15+
"
16+
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20+
" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21+
" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22+
" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23+
24+
function! s:warn(message)
25+
echohl WarningMsg
26+
echom a:message
27+
echohl None
28+
return 0
29+
endfunction
30+
31+
function! fzf#vim#ipc#start(Callback)
32+
if !exists('*job_start') && !exists('*jobstart')
33+
call s:warn('job_start/jobstart function not supported')
34+
return ''
35+
endif
36+
37+
if !executable('mkfifo')
38+
call s:warn('mkfifo is not available')
39+
return ''
40+
endif
41+
42+
call fzf#vim#ipc#stop()
43+
44+
let g:fzf_ipc = { 'fifo': tempname(), 'callback': a:Callback }
45+
if !filereadable(g:fzf_ipc.fifo)
46+
call system('mkfifo '..shellescape(g:fzf_ipc.fifo))
47+
if v:shell_error
48+
call s:warn('Failed to create fifo')
49+
endif
50+
endif
51+
52+
call fzf#vim#ipc#restart()
53+
54+
return g:fzf_ipc.fifo
55+
endfunction
56+
57+
function! fzf#vim#ipc#restart()
58+
if !exists('g:fzf_ipc')
59+
throw 'fzf#vim#ipc not started'
60+
endif
61+
62+
let Callback = g:fzf_ipc.callback
63+
if exists('*job_start')
64+
let g:fzf_ipc.job = job_start(
65+
\ ['cat', g:fzf_ipc.fifo],
66+
\ {'out_cb': { _, msg -> call(Callback, [msg]) },
67+
\ 'exit_cb': { _, status -> status == 0 ? fzf#vim#ipc#restart() : '' }}
68+
\ )
69+
else
70+
let eof = ['']
71+
let g:fzf_ipc.job = jobstart(
72+
\ ['cat', g:fzf_ipc.fifo],
73+
\ {'stdout_buffered': 1,
74+
\ 'on_stdout': { j, msg, e -> msg != eof ? call(Callback, msg) : '' },
75+
\ 'on_exit': { j, status, e -> status == 0 ? fzf#vim#ipc#restart() : '' }}
76+
\ )
77+
endif
78+
endfunction
79+
80+
function! fzf#vim#ipc#stop()
81+
if !exists('g:fzf_ipc')
82+
return
83+
endif
84+
85+
let job = g:fzf_ipc.job
86+
if exists('*job_stop')
87+
call job_stop(job)
88+
else
89+
call jobstop(job)
90+
call jobwait([job])
91+
endif
92+
93+
call delete(g:fzf_ipc.fifo)
94+
unlet g:fzf_ipc
95+
endfunction

0 commit comments

Comments
 (0)