mirror of
https://github.com/junegunn/fzf.git
synced 2025-11-15 14:53:47 -05:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f30ca2923 | ||
|
|
37f2d8f795 | ||
|
|
400e443a0a | ||
|
|
0a8d2996dc | ||
|
|
cfdb00b971 | ||
|
|
9b9ad39143 | ||
|
|
0541c0dbcf | ||
|
|
47b11cb8b4 | ||
|
|
d3da310b92 | ||
|
|
93e0a6a9de | ||
|
|
ac549a853a | ||
|
|
053af9a1c8 | ||
|
|
60112def02 | ||
|
|
2134c0c8a9 |
@@ -1,6 +1,13 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
0.15.5
|
||||||
|
------
|
||||||
|
- Setting foreground color will no longer set background color to black
|
||||||
|
- e.g. `fzf --color fg:153`
|
||||||
|
- `--tiebreak=end` will consider relative position instead of absolute distance
|
||||||
|
- Updated `fzf#wrap` function to respect `g:fzf_colors`
|
||||||
|
|
||||||
0.15.4
|
0.15.4
|
||||||
------
|
------
|
||||||
- Added support for range expression in preview and execute action
|
- Added support for range expression in preview and execute action
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ Note that the environment variables `FZF_DEFAULT_COMMAND` and
|
|||||||
`FZF_DEFAULT_OPTS` also apply here. Refer to [the wiki page][fzf-config] for
|
`FZF_DEFAULT_OPTS` also apply here. Refer to [the wiki page][fzf-config] for
|
||||||
customization.
|
customization.
|
||||||
|
|
||||||
[fzf-config]: https://github.com/junegunn/fzf/wiki/Configuring-FZF-command-(vim)
|
[fzf-config]: https://github.com/junegunn/fzf/wiki/Configuring-Vim-plugin
|
||||||
|
|
||||||
#### `fzf#run`
|
#### `fzf#run`
|
||||||
|
|
||||||
@@ -347,7 +347,8 @@ page](https://github.com/junegunn/fzf/wiki/Examples-(vim)).
|
|||||||
|
|
||||||
`fzf#wrap([name string,] [opts dict,] [fullscreen boolean])` is a helper
|
`fzf#wrap([name string,] [opts dict,] [fullscreen boolean])` is a helper
|
||||||
function that decorates the options dictionary so that it understands
|
function that decorates the options dictionary so that it understands
|
||||||
`g:fzf_layout`, `g:fzf_action`, and `g:fzf_history_dir` like `:FZF`.
|
`g:fzf_layout`, `g:fzf_action`, `g:fzf_colors`, and `g:fzf_history_dir` like
|
||||||
|
`:FZF`.
|
||||||
|
|
||||||
```vim
|
```vim
|
||||||
command! -bang MyStuff
|
command! -bang MyStuff
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ swap=""
|
|||||||
close=""
|
close=""
|
||||||
term=""
|
term=""
|
||||||
[[ -n "$LINES" ]] && lines=$LINES || lines=$(tput lines)
|
[[ -n "$LINES" ]] && lines=$LINES || lines=$(tput lines)
|
||||||
|
[[ -n "$COLUMNS" ]] && columns=$COLUMNS || columns=$(tput cols)
|
||||||
|
|
||||||
help() {
|
help() {
|
||||||
>&2 echo 'usage: fzf-tmux [-u|-d [HEIGHT[%]]] [-l|-r [WIDTH[%]]] [--] [FZF OPTIONS]
|
>&2 echo 'usage: fzf-tmux [-u|-d [HEIGHT[%]]] [-l|-r [WIDTH[%]]] [--] [FZF OPTIONS]
|
||||||
@@ -83,7 +84,7 @@ while [[ $# -gt 0 ]]; do
|
|||||||
else
|
else
|
||||||
if [[ -n "$swap" ]]; then
|
if [[ -n "$swap" ]]; then
|
||||||
if [[ "$arg" =~ ^.l ]]; then
|
if [[ "$arg" =~ ^.l ]]; then
|
||||||
[[ -n "$COLUMNS" ]] && max=$COLUMNS || max=$(tput cols)
|
max=$columns
|
||||||
else
|
else
|
||||||
max=$lines
|
max=$lines
|
||||||
fi
|
fi
|
||||||
@@ -108,7 +109,7 @@ while [[ $# -gt 0 ]]; do
|
|||||||
[[ -n "$skip" ]] && args+=("$arg")
|
[[ -n "$skip" ]] && args+=("$arg")
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ -z "$TMUX" ]] || [[ "$lines" -le 15 ]]; then
|
if [[ -z "$TMUX" || "$opt" =~ ^-h && "$columns" -le 40 || ! "$opt" =~ ^-h && "$lines" -le 15 ]]; then
|
||||||
"$fzf" "${args[@]}"
|
"$fzf" "${args[@]}"
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
|
|||||||
4
install
4
install
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
set -u
|
set -u
|
||||||
|
|
||||||
[[ "$@" =~ --pre ]] && version=0.15.4 pre=1 ||
|
[[ "$@" =~ --pre ]] && version=0.15.5 pre=1 ||
|
||||||
version=0.15.4 pre=0
|
version=0.15.5 pre=0
|
||||||
|
|
||||||
auto_completion=
|
auto_completion=
|
||||||
key_bindings=
|
key_bindings=
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
..
|
..
|
||||||
.TH fzf-tmux 1 "Oct 2016" "fzf 0.15.4" "fzf-tmux - open fzf in tmux split pane"
|
.TH fzf-tmux 1 "Oct 2016" "fzf 0.15.5" "fzf-tmux - open fzf in tmux split pane"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fzf-tmux - open fzf in tmux split pane
|
fzf-tmux - open fzf in tmux split pane
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
..
|
..
|
||||||
.TH fzf 1 "Oct 2016" "fzf 0.15.4" "fzf - a command-line fuzzy finder"
|
.TH fzf 1 "Oct 2016" "fzf 0.15.5" "fzf - a command-line fuzzy finder"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fzf - a command-line fuzzy finder
|
fzf - a command-line fuzzy finder
|
||||||
|
|||||||
@@ -21,6 +21,11 @@
|
|||||||
" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
if exists('g:loaded_fzf')
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
let g:loaded_fzf = 1
|
||||||
|
|
||||||
let s:default_layout = { 'down': '~40%' }
|
let s:default_layout = { 'down': '~40%' }
|
||||||
let s:layout_keys = ['window', 'up', 'down', 'left', 'right']
|
let s:layout_keys = ['window', 'up', 'down', 'left', 'right']
|
||||||
let s:fzf_go = expand('<sfile>:h:h').'/bin/fzf'
|
let s:fzf_go = expand('<sfile>:h:h').'/bin/fzf'
|
||||||
@@ -154,6 +159,22 @@ function! s:common_sink(action, lines) abort
|
|||||||
endtry
|
endtry
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:get_color(attr, ...)
|
||||||
|
for group in a:000
|
||||||
|
let code = synIDattr(synIDtrans(hlID(group)), a:attr, 'cterm')
|
||||||
|
if code =~ '^[0-9]\+$'
|
||||||
|
return code
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:defaults()
|
||||||
|
let rules = copy(get(g:, 'fzf_colors', {}))
|
||||||
|
let colors = join(map(items(filter(map(rules, 'call("s:get_color", v:val)'), '!empty(v:val)')), 'join(v:val, ":")'), ',')
|
||||||
|
return empty(colors) ? '' : ('--color='.colors)
|
||||||
|
endfunction
|
||||||
|
|
||||||
" [name string,] [opts dict,] [fullscreen boolean]
|
" [name string,] [opts dict,] [fullscreen boolean]
|
||||||
function! fzf#wrap(...)
|
function! fzf#wrap(...)
|
||||||
let args = ['', {}, 0]
|
let args = ['', {}, 0]
|
||||||
@@ -185,8 +206,10 @@ function! fzf#wrap(...)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" Colors: g:fzf_colors
|
||||||
|
let opts.options = s:defaults() .' '. get(opts, 'options', '')
|
||||||
|
|
||||||
" History: g:fzf_history_dir
|
" History: g:fzf_history_dir
|
||||||
let opts.options = get(opts, 'options', '')
|
|
||||||
if len(name) && len(get(g:, 'fzf_history_dir', ''))
|
if len(name) && len(get(g:, 'fzf_history_dir', ''))
|
||||||
let dir = expand(g:fzf_history_dir)
|
let dir = expand(g:fzf_history_dir)
|
||||||
if !isdirectory(dir)
|
if !isdirectory(dir)
|
||||||
@@ -289,7 +312,8 @@ function! s:fzf_tmux(dict)
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:splittable(dict)
|
function! s:splittable(dict)
|
||||||
return s:present(a:dict, 'up', 'down', 'left', 'right')
|
return s:present(a:dict, 'up', 'down') && &lines > 15 ||
|
||||||
|
\ s:present(a:dict, 'left', 'right') && &columns > 40
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:pushd(dict)
|
function! s:pushd(dict)
|
||||||
@@ -405,24 +429,25 @@ function! s:split(dict)
|
|||||||
\ 'right': ['vertical botright', 'vertical resize', &columns] }
|
\ 'right': ['vertical botright', 'vertical resize', &columns] }
|
||||||
let ppos = s:getpos()
|
let ppos = s:getpos()
|
||||||
try
|
try
|
||||||
for [dir, triple] in items(directions)
|
|
||||||
let val = get(a:dict, dir, '')
|
|
||||||
if !empty(val)
|
|
||||||
let [cmd, resz, max] = triple
|
|
||||||
if (dir == 'up' || dir == 'down') && val[0] == '~'
|
|
||||||
let sz = s:calc_size(max, val, a:dict)
|
|
||||||
else
|
|
||||||
let sz = s:calc_size(max, val, {})
|
|
||||||
endif
|
|
||||||
execute cmd sz.'new'
|
|
||||||
execute resz sz
|
|
||||||
return [ppos, {}]
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
if s:present(a:dict, 'window')
|
if s:present(a:dict, 'window')
|
||||||
execute a:dict.window
|
execute a:dict.window
|
||||||
else
|
elseif !s:splittable(a:dict)
|
||||||
execute (tabpagenr()-1).'tabnew'
|
execute (tabpagenr()-1).'tabnew'
|
||||||
|
else
|
||||||
|
for [dir, triple] in items(directions)
|
||||||
|
let val = get(a:dict, dir, '')
|
||||||
|
if !empty(val)
|
||||||
|
let [cmd, resz, max] = triple
|
||||||
|
if (dir == 'up' || dir == 'down') && val[0] == '~'
|
||||||
|
let sz = s:calc_size(max, val, a:dict)
|
||||||
|
else
|
||||||
|
let sz = s:calc_size(max, val, {})
|
||||||
|
endif
|
||||||
|
execute cmd sz.'new'
|
||||||
|
execute resz sz
|
||||||
|
return [ppos, {}]
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
endif
|
endif
|
||||||
return [ppos, { '&l:wfw': &l:wfw, '&l:wfh': &l:wfh }]
|
return [ppos, { '&l:wfw': &l:wfw, '&l:wfh': &l:wfh }]
|
||||||
finally
|
finally
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ __fzf_generic_path_completion() {
|
|||||||
setopt localoptions nonomatch
|
setopt localoptions nonomatch
|
||||||
dir="$base"
|
dir="$base"
|
||||||
while [ 1 ]; do
|
while [ 1 ]; do
|
||||||
if [ -z "$dir" -o -d ${~dir} ]; then
|
if [[ -z "$dir" || -d ${~dir} ]]; then
|
||||||
leftover=${base/#"$dir"}
|
leftover=${base/#"$dir"}
|
||||||
leftover=${leftover/#\/}
|
leftover=${leftover/#\/}
|
||||||
[ -z "$dir" ] && dir='.'
|
[ -z "$dir" ] && dir='.'
|
||||||
@@ -111,7 +111,7 @@ _fzf_complete_telnet() {
|
|||||||
|
|
||||||
_fzf_complete_ssh() {
|
_fzf_complete_ssh() {
|
||||||
_fzf_complete '+m' "$@" < <(
|
_fzf_complete '+m' "$@" < <(
|
||||||
cat <(cat ~/.ssh/config /etc/ssh/ssh_config 2> /dev/null | command grep -i '^host' | command grep -v '*') \
|
command cat <(cat ~/.ssh/config /etc/ssh/ssh_config 2> /dev/null | command grep -i '^host' | command grep -v '*') \
|
||||||
<(command grep -oE '^[^ ]+' ~/.ssh/known_hosts | tr ',' '\n' | awk '{ print $1 " " $1 }') \
|
<(command grep -oE '^[^ ]+' ~/.ssh/known_hosts | tr ',' '\n' | awk '{ print $1 " " $1 }') \
|
||||||
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
|
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
|
||||||
awk '{if (length($2) > 0) {print $2}}' | sort -u
|
awk '{if (length($2) > 0) {print $2}}' | sort -u
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ function fzf_key_bindings
|
|||||||
end
|
end
|
||||||
|
|
||||||
function fzf-history-widget
|
function fzf-history-widget
|
||||||
history | eval (__fzfcmd) +s +m --tiebreak=index --toggle-sort=ctrl-r $FZF_CTRL_R_OPTS > $TMPDIR/fzf.result
|
history | eval (__fzfcmd) +s +m --tiebreak=index --toggle-sort=ctrl-r $FZF_CTRL_R_OPTS -q '(commandline)' > $TMPDIR/fzf.result
|
||||||
and commandline (cat $TMPDIR/fzf.result)
|
and commandline -- (cat $TMPDIR/fzf.result)
|
||||||
commandline -f repaint
|
commandline -f repaint
|
||||||
rm -f $TMPDIR/fzf.result
|
rm -f $TMPDIR/fzf.result
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// Current version
|
// Current version
|
||||||
version = "0.15.4"
|
version = "0.15.5"
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
coordinatorDelayMax time.Duration = 100 * time.Millisecond
|
coordinatorDelayMax time.Duration = 100 * time.Millisecond
|
||||||
|
|||||||
@@ -113,7 +113,8 @@ const (
|
|||||||
|
|
||||||
// Pallete
|
// Pallete
|
||||||
const (
|
const (
|
||||||
ColNormal = iota
|
_ = iota
|
||||||
|
ColNormal
|
||||||
ColPrompt
|
ColPrompt
|
||||||
ColMatch
|
ColMatch
|
||||||
ColCurrent
|
ColCurrent
|
||||||
@@ -134,7 +135,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ColorTheme struct {
|
type ColorTheme struct {
|
||||||
UseDefault bool
|
|
||||||
Fg int16
|
Fg int16
|
||||||
Bg int16
|
Bg int16
|
||||||
DarkBg int16
|
DarkBg int16
|
||||||
@@ -168,7 +168,8 @@ type MouseEvent struct {
|
|||||||
var (
|
var (
|
||||||
_buf []byte
|
_buf []byte
|
||||||
_in *os.File
|
_in *os.File
|
||||||
_color func(int, Attr) C.int
|
_color bool
|
||||||
|
_colorFn func(int, Attr) C.int
|
||||||
_colorMap map[int]int
|
_colorMap map[int]int
|
||||||
_prevDownTime time.Time
|
_prevDownTime time.Time
|
||||||
_clickY []int
|
_clickY []int
|
||||||
@@ -176,10 +177,6 @@ var (
|
|||||||
Default16 *ColorTheme
|
Default16 *ColorTheme
|
||||||
Dark256 *ColorTheme
|
Dark256 *ColorTheme
|
||||||
Light256 *ColorTheme
|
Light256 *ColorTheme
|
||||||
FG int
|
|
||||||
CurrentFG int
|
|
||||||
BG int
|
|
||||||
DarkBG int
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Window struct {
|
type Window struct {
|
||||||
@@ -192,12 +189,16 @@ type Window struct {
|
|||||||
|
|
||||||
func NewWindow(top int, left int, width int, height int, border bool) *Window {
|
func NewWindow(top int, left int, width int, height int, border bool) *Window {
|
||||||
win := C.newwin(C.int(height), C.int(width), C.int(top), C.int(left))
|
win := C.newwin(C.int(height), C.int(width), C.int(top), C.int(left))
|
||||||
|
if _color {
|
||||||
|
C.wbkgd(win, C.chtype(C.COLOR_PAIR(ColNormal)))
|
||||||
|
}
|
||||||
if border {
|
if border {
|
||||||
attr := _color(ColBorder, 0)
|
attr := _colorFn(ColBorder, 0)
|
||||||
C.wattron(win, attr)
|
C.wattron(win, attr)
|
||||||
C.box(win, 0, 0)
|
C.box(win, 0, 0)
|
||||||
C.wattroff(win, attr)
|
C.wattroff(win, attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Window{
|
return &Window{
|
||||||
win: win,
|
win: win,
|
||||||
Top: top,
|
Top: top,
|
||||||
@@ -209,7 +210,6 @@ func NewWindow(top int, left int, width int, height int, border bool) *Window {
|
|||||||
|
|
||||||
func EmptyTheme() *ColorTheme {
|
func EmptyTheme() *ColorTheme {
|
||||||
return &ColorTheme{
|
return &ColorTheme{
|
||||||
UseDefault: true,
|
|
||||||
Fg: colUndefined,
|
Fg: colUndefined,
|
||||||
Bg: colUndefined,
|
Bg: colUndefined,
|
||||||
DarkBg: colUndefined,
|
DarkBg: colUndefined,
|
||||||
@@ -230,9 +230,8 @@ func init() {
|
|||||||
_clickY = []int{}
|
_clickY = []int{}
|
||||||
_colorMap = make(map[int]int)
|
_colorMap = make(map[int]int)
|
||||||
Default16 = &ColorTheme{
|
Default16 = &ColorTheme{
|
||||||
UseDefault: true,
|
Fg: colDefault,
|
||||||
Fg: 15,
|
Bg: colDefault,
|
||||||
Bg: 0,
|
|
||||||
DarkBg: C.COLOR_BLACK,
|
DarkBg: C.COLOR_BLACK,
|
||||||
Prompt: C.COLOR_BLUE,
|
Prompt: C.COLOR_BLUE,
|
||||||
Match: C.COLOR_GREEN,
|
Match: C.COLOR_GREEN,
|
||||||
@@ -245,9 +244,8 @@ func init() {
|
|||||||
Header: C.COLOR_CYAN,
|
Header: C.COLOR_CYAN,
|
||||||
Border: C.COLOR_BLACK}
|
Border: C.COLOR_BLACK}
|
||||||
Dark256 = &ColorTheme{
|
Dark256 = &ColorTheme{
|
||||||
UseDefault: true,
|
Fg: colDefault,
|
||||||
Fg: 15,
|
Bg: colDefault,
|
||||||
Bg: 0,
|
|
||||||
DarkBg: 236,
|
DarkBg: 236,
|
||||||
Prompt: 110,
|
Prompt: 110,
|
||||||
Match: 108,
|
Match: 108,
|
||||||
@@ -260,9 +258,8 @@ func init() {
|
|||||||
Header: 109,
|
Header: 109,
|
||||||
Border: 59}
|
Border: 59}
|
||||||
Light256 = &ColorTheme{
|
Light256 = &ColorTheme{
|
||||||
UseDefault: true,
|
Fg: colDefault,
|
||||||
Fg: 15,
|
Bg: colDefault,
|
||||||
Bg: 0,
|
|
||||||
DarkBg: 251,
|
DarkBg: 251,
|
||||||
Prompt: 25,
|
Prompt: 25,
|
||||||
Match: 66,
|
Match: 66,
|
||||||
@@ -278,7 +275,7 @@ func init() {
|
|||||||
|
|
||||||
func attrColored(pair int, a Attr) C.int {
|
func attrColored(pair int, a Attr) C.int {
|
||||||
var attr C.int
|
var attr C.int
|
||||||
if pair > ColNormal {
|
if pair > 0 {
|
||||||
attr = C.COLOR_PAIR(C.int(pair))
|
attr = C.COLOR_PAIR(C.int(pair))
|
||||||
}
|
}
|
||||||
return attr | C.int(a)
|
return attr | C.int(a)
|
||||||
@@ -344,7 +341,8 @@ func Init(theme *ColorTheme, black bool, mouse bool) {
|
|||||||
C.noecho()
|
C.noecho()
|
||||||
C.raw() // stty dsusp undef
|
C.raw() // stty dsusp undef
|
||||||
|
|
||||||
if theme != nil {
|
_color = theme != nil
|
||||||
|
if _color {
|
||||||
C.start_color()
|
C.start_color()
|
||||||
var baseTheme *ColorTheme
|
var baseTheme *ColorTheme
|
||||||
if C.tigetnum(C.CString("colors")) >= 256 {
|
if C.tigetnum(C.CString("colors")) >= 256 {
|
||||||
@@ -353,52 +351,57 @@ func Init(theme *ColorTheme, black bool, mouse bool) {
|
|||||||
baseTheme = Default16
|
baseTheme = Default16
|
||||||
}
|
}
|
||||||
initPairs(baseTheme, theme, black)
|
initPairs(baseTheme, theme, black)
|
||||||
_color = attrColored
|
C.bkgd(C.chtype(C.COLOR_PAIR(ColNormal)))
|
||||||
|
_colorFn = attrColored
|
||||||
} else {
|
} else {
|
||||||
_color = attrMono
|
_colorFn = attrMono
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func override(a int16, b int16) C.short {
|
func override(baseTheme *ColorTheme, theme *ColorTheme) {
|
||||||
if b == colUndefined {
|
o := func(a int16, b int16) int16 {
|
||||||
return C.short(a)
|
if b == colUndefined {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
return C.short(b)
|
theme.Fg = o(baseTheme.Fg, theme.Fg)
|
||||||
|
theme.Bg = o(baseTheme.Bg, theme.Bg)
|
||||||
|
theme.DarkBg = o(baseTheme.DarkBg, theme.DarkBg)
|
||||||
|
theme.Prompt = o(baseTheme.Prompt, theme.Prompt)
|
||||||
|
theme.Match = o(baseTheme.Match, theme.Match)
|
||||||
|
theme.Current = o(baseTheme.Current, theme.Current)
|
||||||
|
theme.CurrentMatch = o(baseTheme.CurrentMatch, theme.CurrentMatch)
|
||||||
|
theme.Spinner = o(baseTheme.Spinner, theme.Spinner)
|
||||||
|
theme.Info = o(baseTheme.Info, theme.Info)
|
||||||
|
theme.Cursor = o(baseTheme.Cursor, theme.Cursor)
|
||||||
|
theme.Selected = o(baseTheme.Selected, theme.Selected)
|
||||||
|
theme.Header = o(baseTheme.Header, theme.Header)
|
||||||
|
theme.Border = o(baseTheme.Border, theme.Border)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initPairs(baseTheme *ColorTheme, theme *ColorTheme, black bool) {
|
func initPairs(baseTheme *ColorTheme, theme *ColorTheme, black bool) {
|
||||||
fg := override(baseTheme.Fg, theme.Fg)
|
|
||||||
bg := override(baseTheme.Bg, theme.Bg)
|
|
||||||
if black {
|
if black {
|
||||||
bg = C.COLOR_BLACK
|
theme.Bg = C.COLOR_BLACK
|
||||||
} else if theme.UseDefault {
|
|
||||||
fg = colDefault
|
|
||||||
bg = colDefault
|
|
||||||
C.use_default_colors()
|
|
||||||
}
|
|
||||||
if theme.UseDefault {
|
|
||||||
FG = colDefault
|
|
||||||
BG = colDefault
|
|
||||||
} else {
|
|
||||||
FG = int(fg)
|
|
||||||
BG = int(bg)
|
|
||||||
C.assume_default_colors(C.int(override(baseTheme.Fg, theme.Fg)), C.int(bg))
|
|
||||||
}
|
}
|
||||||
|
// Updates theme
|
||||||
|
override(baseTheme, theme)
|
||||||
|
|
||||||
currentFG := override(baseTheme.Current, theme.Current)
|
C.assume_default_colors(C.int(theme.Fg), C.int(theme.Bg))
|
||||||
darkBG := override(baseTheme.DarkBg, theme.DarkBg)
|
initPair := func(group C.short, fg int16, bg int16) {
|
||||||
CurrentFG = int(currentFG)
|
C.init_pair(group, C.short(fg), C.short(bg))
|
||||||
DarkBG = int(darkBG)
|
}
|
||||||
C.init_pair(ColPrompt, override(baseTheme.Prompt, theme.Prompt), bg)
|
initPair(ColNormal, theme.Fg, theme.Bg)
|
||||||
C.init_pair(ColMatch, override(baseTheme.Match, theme.Match), bg)
|
initPair(ColPrompt, theme.Prompt, theme.Bg)
|
||||||
C.init_pair(ColCurrent, currentFG, darkBG)
|
initPair(ColMatch, theme.Match, theme.Bg)
|
||||||
C.init_pair(ColCurrentMatch, override(baseTheme.CurrentMatch, theme.CurrentMatch), darkBG)
|
initPair(ColCurrent, theme.Current, theme.DarkBg)
|
||||||
C.init_pair(ColSpinner, override(baseTheme.Spinner, theme.Spinner), bg)
|
initPair(ColCurrentMatch, theme.CurrentMatch, theme.DarkBg)
|
||||||
C.init_pair(ColInfo, override(baseTheme.Info, theme.Info), bg)
|
initPair(ColSpinner, theme.Spinner, theme.Bg)
|
||||||
C.init_pair(ColCursor, override(baseTheme.Cursor, theme.Cursor), darkBG)
|
initPair(ColInfo, theme.Info, theme.Bg)
|
||||||
C.init_pair(ColSelected, override(baseTheme.Selected, theme.Selected), darkBG)
|
initPair(ColCursor, theme.Cursor, theme.DarkBg)
|
||||||
C.init_pair(ColHeader, override(baseTheme.Header, theme.Header), bg)
|
initPair(ColSelected, theme.Selected, theme.DarkBg)
|
||||||
C.init_pair(ColBorder, override(baseTheme.Border, theme.Border), bg)
|
initPair(ColHeader, theme.Header, theme.Bg)
|
||||||
|
initPair(ColBorder, theme.Border, theme.Bg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Close() {
|
func Close() {
|
||||||
@@ -656,7 +659,7 @@ func (w *Window) Print(text string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) CPrint(pair int, a Attr, text string) {
|
func (w *Window) CPrint(pair int, a Attr, text string) {
|
||||||
attr := _color(pair, a)
|
attr := _colorFn(pair, a)
|
||||||
C.wattron(w.win, attr)
|
C.wattron(w.win, attr)
|
||||||
w.Print(text)
|
w.Print(text)
|
||||||
C.wattroff(w.win, attr)
|
C.wattroff(w.win, attr)
|
||||||
@@ -683,7 +686,7 @@ func (w *Window) Fill(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) CFill(str string, fg int, bg int, a Attr) bool {
|
func (w *Window) CFill(str string, fg int, bg int, a Attr) bool {
|
||||||
attr := _color(PairFor(fg, bg), a)
|
attr := _colorFn(PairFor(fg, bg), a)
|
||||||
C.wattron(w.win, attr)
|
C.wattron(w.win, attr)
|
||||||
ret := w.Fill(str)
|
ret := w.Fill(str)
|
||||||
C.wattroff(w.win, attr)
|
C.wattroff(w.win, attr)
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ func nextString(args []string, i *int, message string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func optionalNextString(args []string, i *int) string {
|
func optionalNextString(args []string, i *int) string {
|
||||||
if len(args) > *i+1 {
|
if len(args) > *i+1 && !strings.HasPrefix(args[*i+1], "-") {
|
||||||
*i++
|
*i++
|
||||||
return args[*i]
|
return args[*i]
|
||||||
}
|
}
|
||||||
@@ -499,10 +499,8 @@ func parseTheme(defaultTheme *curses.ColorTheme, str string) *curses.ColorTheme
|
|||||||
switch pair[0] {
|
switch pair[0] {
|
||||||
case "fg":
|
case "fg":
|
||||||
theme.Fg = ansi
|
theme.Fg = ansi
|
||||||
theme.UseDefault = theme.UseDefault && ansi < 0
|
|
||||||
case "bg":
|
case "bg":
|
||||||
theme.Bg = ansi
|
theme.Bg = ansi
|
||||||
theme.UseDefault = theme.UseDefault && ansi < 0
|
|
||||||
case "fg+":
|
case "fg+":
|
||||||
theme.Current = ansi
|
theme.Current = ansi
|
||||||
case "bg+":
|
case "bg+":
|
||||||
|
|||||||
@@ -299,20 +299,14 @@ func TestColorSpec(t *testing.T) {
|
|||||||
}
|
}
|
||||||
customized.Fg = curses.Dark256.Fg
|
customized.Fg = curses.Dark256.Fg
|
||||||
customized.Bg = curses.Dark256.Bg
|
customized.Bg = curses.Dark256.Bg
|
||||||
if *curses.Dark256 == *customized {
|
if *curses.Dark256 != *customized {
|
||||||
t.Errorf("colors should now be equivalent")
|
t.Errorf("colors should now be equivalent: %v, %v", curses.Dark256, customized)
|
||||||
}
|
}
|
||||||
|
|
||||||
customized = parseTheme(theme, "fg:231,dark,bg:232")
|
customized = parseTheme(theme, "fg:231,dark,bg:232")
|
||||||
if customized.Fg != curses.Dark256.Fg || customized.Bg == curses.Dark256.Bg {
|
if customized.Fg != curses.Dark256.Fg || customized.Bg == curses.Dark256.Bg {
|
||||||
t.Errorf("color not customized")
|
t.Errorf("color not customized")
|
||||||
}
|
}
|
||||||
if customized.UseDefault {
|
|
||||||
t.Errorf("not using default colors")
|
|
||||||
}
|
|
||||||
if !curses.Dark256.UseDefault {
|
|
||||||
t.Errorf("using default colors")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseNilTheme(t *testing.T) {
|
func TestParseNilTheme(t *testing.T) {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func buildResult(item *Item, offsets []Offset, score int, trimLen int) *Result {
|
|||||||
case byLength:
|
case byLength:
|
||||||
// If offsets is empty, trimLen will be 0, but we don't care
|
// If offsets is empty, trimLen will be 0, but we don't care
|
||||||
val = util.AsUint16(trimLen)
|
val = util.AsUint16(trimLen)
|
||||||
case byBegin:
|
case byBegin, byEnd:
|
||||||
if validOffsetFound {
|
if validOffsetFound {
|
||||||
whitePrefixLen := 0
|
whitePrefixLen := 0
|
||||||
for idx := 0; idx < numChars; idx++ {
|
for idx := 0; idx < numChars; idx++ {
|
||||||
@@ -67,11 +67,11 @@ func buildResult(item *Item, offsets []Offset, score int, trimLen int) *Result {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val = util.AsUint16(minBegin - whitePrefixLen)
|
if criterion == byBegin {
|
||||||
}
|
val = util.AsUint16(minBegin - whitePrefixLen)
|
||||||
case byEnd:
|
} else {
|
||||||
if validOffsetFound {
|
val = util.AsUint16(math.MaxUint16 - math.MaxUint16*(maxEnd-whitePrefixLen)/trimLen)
|
||||||
val = util.AsUint16(1 + numChars - maxEnd)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.rank.points[idx] = val
|
result.rank.points[idx] = val
|
||||||
@@ -92,13 +92,13 @@ func minRank() rank {
|
|||||||
return rank{index: 0, points: [4]uint16{math.MaxUint16, 0, 0, 0}}
|
return rank{index: 0, points: [4]uint16{math.MaxUint16, 0, 0, 0}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (result *Result) colorOffsets(matchOffsets []Offset, color int, attr curses.Attr, current bool) []colorOffset {
|
func (result *Result) colorOffsets(matchOffsets []Offset, theme *curses.ColorTheme, color int, attr curses.Attr, current bool) []colorOffset {
|
||||||
itemColors := result.item.Colors()
|
itemColors := result.item.Colors()
|
||||||
|
|
||||||
|
// No ANSI code, or --color=no
|
||||||
if len(itemColors) == 0 {
|
if len(itemColors) == 0 {
|
||||||
var offsets []colorOffset
|
var offsets []colorOffset
|
||||||
for _, off := range matchOffsets {
|
for _, off := range matchOffsets {
|
||||||
|
|
||||||
offsets = append(offsets, colorOffset{offset: [2]int32{off[0], off[1]}, color: color, attr: attr})
|
offsets = append(offsets, colorOffset{offset: [2]int32{off[0], off[1]}, color: color, attr: attr})
|
||||||
}
|
}
|
||||||
return offsets
|
return offsets
|
||||||
@@ -149,17 +149,17 @@ func (result *Result) colorOffsets(matchOffsets []Offset, color int, attr curses
|
|||||||
fg := ansi.color.fg
|
fg := ansi.color.fg
|
||||||
if fg == -1 {
|
if fg == -1 {
|
||||||
if current {
|
if current {
|
||||||
fg = curses.CurrentFG
|
fg = int(theme.Current)
|
||||||
} else {
|
} else {
|
||||||
fg = curses.FG
|
fg = int(theme.Fg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bg := ansi.color.bg
|
bg := ansi.color.bg
|
||||||
if bg == -1 {
|
if bg == -1 {
|
||||||
if current {
|
if current {
|
||||||
bg = curses.DarkBG
|
bg = int(theme.DarkBg)
|
||||||
} else {
|
} else {
|
||||||
bg = curses.BG
|
bg = int(theme.Bg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
colors = append(colors, colorOffset{
|
colors = append(colors, colorOffset{
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ func TestColorOffset(t *testing.T) {
|
|||||||
ansiOffset{[2]int32{33, 40}, ansiState{4, 8, curses.Bold}}}}}
|
ansiOffset{[2]int32{33, 40}, ansiState{4, 8, curses.Bold}}}}}
|
||||||
// [{[0 5] 9 false} {[5 15] 99 false} {[15 20] 9 false} {[22 25] 10 true} {[25 35] 99 false} {[35 40] 11 true}]
|
// [{[0 5] 9 false} {[5 15] 99 false} {[15 20] 9 false} {[22 25] 10 true} {[25 35] 99 false} {[35 40] 11 true}]
|
||||||
|
|
||||||
colors := item.colorOffsets(offsets, 99, 0, true)
|
colors := item.colorOffsets(offsets, curses.Dark256, 99, 0, true)
|
||||||
assert := func(idx int, b int32, e int32, c int, bold bool) {
|
assert := func(idx int, b int32, e int32, c int, bold bool) {
|
||||||
var attr curses.Attr
|
var attr curses.Attr
|
||||||
if bold {
|
if bold {
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ type Terminal struct {
|
|||||||
suppress bool
|
suppress bool
|
||||||
startChan chan bool
|
startChan chan bool
|
||||||
slab *util.Slab
|
slab *util.Slab
|
||||||
|
theme *C.ColorTheme
|
||||||
}
|
}
|
||||||
|
|
||||||
type selectedItem struct {
|
type selectedItem struct {
|
||||||
@@ -295,6 +296,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
|||||||
mutex: sync.Mutex{},
|
mutex: sync.Mutex{},
|
||||||
suppress: true,
|
suppress: true,
|
||||||
slab: util.MakeSlab(slab16Size, slab32Size),
|
slab: util.MakeSlab(slab16Size, slab32Size),
|
||||||
|
theme: opts.Theme,
|
||||||
startChan: make(chan bool, 1),
|
startChan: make(chan bool, 1),
|
||||||
initFunc: func() {
|
initFunc: func() {
|
||||||
C.Init(opts.Theme, opts.Black, opts.Mouse)
|
C.Init(opts.Theme, opts.Black, opts.Mouse)
|
||||||
@@ -637,7 +639,7 @@ func (t *Terminal) printItem(result *Result, i int, current bool) {
|
|||||||
} else {
|
} else {
|
||||||
t.window.Print(" ")
|
t.window.Print(" ")
|
||||||
}
|
}
|
||||||
t.printHighlighted(result, 0, 0, C.ColMatch, false)
|
t.printHighlighted(result, 0, C.ColNormal, C.ColMatch, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,7 +720,7 @@ func (t *Terminal) printHighlighted(result *Result, attr C.Attr, col1 int, col2
|
|||||||
maxe = util.Max(maxe, int(offset[1]))
|
maxe = util.Max(maxe, int(offset[1]))
|
||||||
}
|
}
|
||||||
|
|
||||||
offsets := result.colorOffsets(charOffsets, col2, attr, current)
|
offsets := result.colorOffsets(charOffsets, t.theme, col2, attr, current)
|
||||||
maxWidth := t.window.Width - 3
|
maxWidth := t.window.Width - 3
|
||||||
maxe = util.Constrain(maxe+util.Min(maxWidth/2-2, t.hscrollOff), 0, len(text))
|
maxe = util.Constrain(maxe+util.Min(maxWidth/2-2, t.hscrollOff), 0, len(text))
|
||||||
if overflow(text, maxWidth) {
|
if overflow(text, maxWidth) {
|
||||||
|
|||||||
@@ -143,6 +143,10 @@ Execute (fzf#wrap):
|
|||||||
Assert opts.options =~ '--history /tmp/foobar'
|
Assert opts.options =~ '--history /tmp/foobar'
|
||||||
Assert opts.options =~ '--color light'
|
Assert opts.options =~ '--color light'
|
||||||
|
|
||||||
|
let g:fzf_colors = { 'fg': ['fg', 'Error'] }
|
||||||
|
let opts = fzf#wrap({})
|
||||||
|
Assert opts.options =~ '^--color=fg:'
|
||||||
|
|
||||||
Execute (Cleanup):
|
Execute (Cleanup):
|
||||||
unlet g:dir
|
unlet g:dir
|
||||||
Restore
|
Restore
|
||||||
|
|||||||
@@ -136,8 +136,10 @@ class Tmux
|
|||||||
def prepare
|
def prepare
|
||||||
tries = 0
|
tries = 0
|
||||||
begin
|
begin
|
||||||
self.send_keys 'C-u', 'hello', 'Right'
|
self.until do |lines|
|
||||||
self.until { |lines| lines[-1].end_with?('hello') }
|
self.send_keys 'C-u', 'hello'
|
||||||
|
lines[-1].end_with?('hello')
|
||||||
|
end
|
||||||
rescue Exception
|
rescue Exception
|
||||||
(tries += 1) < 5 ? retry : raise
|
(tries += 1) < 5 ? retry : raise
|
||||||
end
|
end
|
||||||
@@ -604,8 +606,8 @@ class TestGoFZF < TestBase
|
|||||||
], `#{FZF} -fo --tiebreak=end < #{tempname}`.split($/)
|
], `#{FZF} -fo --tiebreak=end < #{tempname}`.split($/)
|
||||||
|
|
||||||
assert_equal [
|
assert_equal [
|
||||||
' xxxxoxxx',
|
|
||||||
'xxxxxoxxx',
|
'xxxxxoxxx',
|
||||||
|
' xxxxoxxx',
|
||||||
'xxxxoxxxx',
|
'xxxxoxxxx',
|
||||||
'xxxoxxxxxx',
|
'xxxoxxxxxx',
|
||||||
'xxoxxxxxxx',
|
'xxoxxxxxxx',
|
||||||
|
|||||||
Reference in New Issue
Block a user