mirror of
https://github.com/junegunn/fzf.git
synced 2025-12-06 17:24:07 -05:00
Compare commits
7 Commits
dependabot
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b473477c22 | ||
|
|
fcc4178bca | ||
|
|
cfc37caabc | ||
|
|
af2a81dc02 | ||
|
|
be5a687281 | ||
|
|
771e35b972 | ||
|
|
60a5be1e65 |
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/depsreview.yaml
vendored
2
.github/workflows/depsreview.yaml
vendored
@@ -9,6 +9,6 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v5
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@v4
|
uses: actions/dependency-review-action@v4
|
||||||
|
|||||||
2
.github/workflows/linux.yml
vendored
2
.github/workflows/linux.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/macos.yml
vendored
2
.github/workflows/macos.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/sponsors.yml
vendored
2
.github/workflows/sponsors.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout 🛎️
|
- name: Checkout 🛎️
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Generate Sponsors 💖
|
- name: Generate Sponsors 💖
|
||||||
uses: JamesIves/github-sponsors-readme-action@v1
|
uses: JamesIves/github-sponsors-readme-action@v1
|
||||||
|
|||||||
2
.github/workflows/typos.yml
vendored
2
.github/workflows/typos.yml
vendored
@@ -6,5 +6,5 @@ jobs:
|
|||||||
name: Spell Check with Typos
|
name: Spell Check with Typos
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v5
|
||||||
- uses: crate-ci/typos@v1.29.4
|
- uses: crate-ci/typos@v1.29.4
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ Table of Contents
|
|||||||
* [fzf Theme Playground](#fzf-theme-playground)
|
* [fzf Theme Playground](#fzf-theme-playground)
|
||||||
* [Related projects](#related-projects)
|
* [Related projects](#related-projects)
|
||||||
* [License](#license)
|
* [License](#license)
|
||||||
|
* [Goods](#goods)
|
||||||
* [Sponsors :heart:](#sponsors-heart)
|
* [Sponsors :heart:](#sponsors-heart)
|
||||||
|
|
||||||
<!-- vim-markdown-toc -->
|
<!-- vim-markdown-toc -->
|
||||||
@@ -999,6 +1000,11 @@ The MIT License (MIT)
|
|||||||
|
|
||||||
Copyright (c) 2013-2025 Junegunn Choi
|
Copyright (c) 2013-2025 Junegunn Choi
|
||||||
|
|
||||||
|
Goods
|
||||||
|
-----
|
||||||
|
|
||||||
|
Grab fzf T-shirts, mugs, and stickers here: https://commitgoods.com/collections/fzf
|
||||||
|
|
||||||
Sponsors :heart:
|
Sponsors :heart:
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|||||||
@@ -272,6 +272,7 @@ color mappings. Each entry is separated by a comma and/or whitespaces.
|
|||||||
\fBgutter \fRGutter on the left
|
\fBgutter \fRGutter on the left
|
||||||
\fBcurrent\-hl (hl+) \fRHighlighted substrings (current line)
|
\fBcurrent\-hl (hl+) \fRHighlighted substrings (current line)
|
||||||
\fBalt\-bg \fRAlternate background color to create striped lines
|
\fBalt\-bg \fRAlternate background color to create striped lines
|
||||||
|
\fBalt\-gutter \fRAlternate gutter color to create the striped pattern
|
||||||
\fBquery (input\-fg) \fRQuery string
|
\fBquery (input\-fg) \fRQuery string
|
||||||
\fBghost \fRGhost text (\fB\-\-ghost\fR, \fBdim\fR applied by default)
|
\fBghost \fRGhost text (\fB\-\-ghost\fR, \fBdim\fR applied by default)
|
||||||
\fBdisabled \fRQuery string when search is disabled (\fB\-\-disabled\fR)
|
\fBdisabled \fRQuery string when search is disabled (\fB\-\-disabled\fR)
|
||||||
@@ -740,7 +741,7 @@ ENVIRONMENT VARIABLES EXPORTED TO CHILD PROCESSES.
|
|||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
\fB# Prepend the current cursor position in yellow
|
\fB# Prepend the current cursor position in yellow
|
||||||
fzf \-\-info\-command='echo \-e "\\x1b[33;1m$FZF_POS\\x1b[m/$FZF_INFO 💛"'\fR
|
fzf \-\-info\-command='printf "\\x1b[33;1m$FZF_POS\\x1b[m/$FZF_INFO 💛"'\fR
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B "\-\-no\-info"
|
.B "\-\-no\-info"
|
||||||
@@ -840,6 +841,9 @@ e.g.
|
|||||||
# This won't work properly without 'f' flag due to ARG_MAX limit.
|
# This won't work properly without 'f' flag due to ARG_MAX limit.
|
||||||
seq 100000 | fzf \-\-preview "awk '{sum+=\\$1} END {print sum}' {*f}"\fR
|
seq 100000 | fzf \-\-preview "awk '{sum+=\\$1} END {print sum}' {*f}"\fR
|
||||||
|
|
||||||
|
\fB# Use {+f} to get the selected items as a line-separated list
|
||||||
|
seq 100 | fzf \-\-multi \-\-bind 'enter:become:cat {+f}'\fR
|
||||||
|
|
||||||
Also,
|
Also,
|
||||||
|
|
||||||
* \fB{q}\fR is replaced to the current query string
|
* \fB{q}\fR is replaced to the current query string
|
||||||
@@ -2105,7 +2109,7 @@ payload of HTTP POST request to the \fB\-\-listen\fR server.
|
|||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
\fB# Disallow selecting an empty line
|
\fB# Disallow selecting an empty line
|
||||||
echo \-e "1. Hello\\n2. Goodbye\\n\\n3. Exit" |
|
printf "1. Hello\\n2. Goodbye\\n\\n3. Exit" |
|
||||||
fzf \-\-height '~100%' \-\-reverse \-\-header 'Select one' \\
|
fzf \-\-height '~100%' \-\-reverse \-\-header 'Select one' \\
|
||||||
\-\-bind 'enter:transform:[[ \-n {} ]] &&
|
\-\-bind 'enter:transform:[[ \-n {} ]] &&
|
||||||
echo accept ||
|
echo accept ||
|
||||||
|
|||||||
@@ -128,25 +128,52 @@ fi
|
|||||||
|
|
||||||
# CTRL-R - Paste the selected command from history into the command line
|
# CTRL-R - Paste the selected command from history into the command line
|
||||||
fzf-history-widget() {
|
fzf-history-widget() {
|
||||||
local selected
|
local selected extracted_with_perl=0
|
||||||
setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases noglob nobash_rematch 2> /dev/null
|
setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases no_glob no_ksharrays extendedglob 2> /dev/null
|
||||||
# Ensure the module is loaded if not already, and the required features, such
|
# Ensure the module is loaded if not already, and the required features, such
|
||||||
# as the associative 'history' array, which maps event numbers to full history
|
# as the associative 'history' array, which maps event numbers to full history
|
||||||
# lines, are set. Also, make sure Perl is installed for multi-line output.
|
# lines, are set. Also, make sure Perl is installed for multi-line output.
|
||||||
if zmodload -F zsh/parameter p:{commands,history} 2>/dev/null && (( ${+commands[perl]} )); then
|
if zmodload -F zsh/parameter p:{commands,history} 2>/dev/null && (( ${+commands[perl]} )); then
|
||||||
selected="$(printf '%s\t%s\000' "${(kv)history[@]}" |
|
selected="$(printf '%s\t%s\000' "${(kv)history[@]}" |
|
||||||
perl -0 -ne 'if (!$seen{(/^\s*[0-9]+\**\t(.*)/s, $1)}++) { s/\n/\n\t/g; print; }' |
|
perl -0 -ne 'if (!$seen{(/^\s*[0-9]+\**\t(.*)/s, $1)}++) { s/\n/\n\t/g; print; }' |
|
||||||
FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,alt-r:toggle-raw --wrap-sign '\t↳ ' --highlight-line ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m --read0") \
|
FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,alt-r:toggle-raw --wrap-sign '\t↳ ' --highlight-line --multi ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} --read0") \
|
||||||
FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd))"
|
FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd))"
|
||||||
|
extracted_with_perl=1
|
||||||
else
|
else
|
||||||
selected="$(fc -rl 1 | __fzf_exec_awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' |
|
selected="$(fc -rl 1 | __fzf_exec_awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' |
|
||||||
FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,alt-r:toggle-raw --wrap-sign '\t↳ ' --highlight-line ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m") \
|
FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,alt-r:toggle-raw --wrap-sign '\t↳ ' --highlight-line --multi ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER}") \
|
||||||
FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd))"
|
FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd))"
|
||||||
fi
|
fi
|
||||||
local ret=$?
|
local ret=$?
|
||||||
|
local -a cmds
|
||||||
|
# Avoid leaking auto assigned values when using backreferences '(#b)'
|
||||||
|
local -a mbegin mend match
|
||||||
if [ -n "$selected" ]; then
|
if [ -n "$selected" ]; then
|
||||||
if [[ $(__fzf_exec_awk '{print $1; exit}' <<< "$selected") =~ ^[1-9][0-9]* ]]; then
|
# Heuristic to check if the selected value is from history or a custom query
|
||||||
zle vi-fetch-history -n $MATCH
|
if ((( extracted_with_perl )) && [[ $selected == <->$'\t'* ]]) ||
|
||||||
|
((( ! extracted_with_perl )) && [[ $selected == [[:blank:]]#<->( |\* )* ]]); then
|
||||||
|
# Split at newlines
|
||||||
|
for line in ${(ps:\n:)selected}; do
|
||||||
|
if (( extracted_with_perl )); then
|
||||||
|
if [[ $line == (#b)(<->)(#B)$'\t'* ]]; then
|
||||||
|
(( ${+history[${match[1]}]} )) && cmds+=("${history[${match[1]}]}")
|
||||||
|
fi
|
||||||
|
elif [[ $line == [[:blank:]]#(#b)(<->)(#B)( |\* )* ]]; then
|
||||||
|
# Avoid $history array: lags behind 'fc' on foreign commands (*)
|
||||||
|
# https://zsh.org/mla/users/2024/msg00692.html
|
||||||
|
# Push BUFFER onto stack; fetch and save history entry from BUFFER; restore
|
||||||
|
zle .push-line
|
||||||
|
zle vi-fetch-history -n ${match[1]}
|
||||||
|
(( ${#BUFFER} )) && cmds+=("${BUFFER}")
|
||||||
|
BUFFER=""
|
||||||
|
zle .get-line
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if (( ${#cmds[@]} )); then
|
||||||
|
# Join by newline after stripping trailing newlines from each command
|
||||||
|
BUFFER="${(pj:\n:)${(@)cmds%%$'\n'#}}"
|
||||||
|
CURSOR=${#BUFFER}
|
||||||
|
fi
|
||||||
else # selected is a custom query, not from history
|
else # selected is a custom query, not from history
|
||||||
LBUFFER="$selected"
|
LBUFFER="$selected"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -445,7 +445,9 @@ func FuzzyMatchV2(caseSensitive bool, normalize bool, forward bool, input *util.
|
|||||||
|
|
||||||
// Since O(nm) algorithm can be prohibitively expensive for large input,
|
// Since O(nm) algorithm can be prohibitively expensive for large input,
|
||||||
// we fall back to the greedy algorithm.
|
// we fall back to the greedy algorithm.
|
||||||
if slab != nil && N*M > cap(slab.I16) {
|
// Also, we should not allow a very long pattern to avoid 16-bit integer
|
||||||
|
// overflow in the score matrix. 1000 is a safe limit.
|
||||||
|
if slab != nil && N*M > cap(slab.I16) || M > 1000 {
|
||||||
return FuzzyMatchV1(caseSensitive, normalize, forward, input, pattern, withPos, slab)
|
return FuzzyMatchV1(caseSensitive, normalize, forward, input, pattern, withPos, slab)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1476,6 +1476,8 @@ func parseTheme(defaultTheme *tui.ColorTheme, str string) (*tui.ColorTheme, *tui
|
|||||||
mergeAttr(&theme.Nomatch)
|
mergeAttr(&theme.Nomatch)
|
||||||
case "gutter":
|
case "gutter":
|
||||||
mergeAttr(&theme.Gutter)
|
mergeAttr(&theme.Gutter)
|
||||||
|
case "alt-gutter":
|
||||||
|
mergeAttr(&theme.AltGutter)
|
||||||
case "hl":
|
case "hl":
|
||||||
mergeAttr(&theme.Match)
|
mergeAttr(&theme.Match)
|
||||||
case "current-hl", "hl+":
|
case "current-hl", "hl+":
|
||||||
|
|||||||
@@ -3202,14 +3202,22 @@ func (t *Terminal) renderEmptyLine(line int, barRange [2]int) {
|
|||||||
t.renderBar(line, barRange)
|
t.renderBar(line, barRange)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Terminal) gutter(current bool) {
|
func (t *Terminal) gutter(current bool, alt bool) {
|
||||||
var color tui.ColorPair
|
var color tui.ColorPair
|
||||||
if current {
|
if current {
|
||||||
color = tui.ColCurrentCursorEmpty
|
color = tui.ColCurrentCursorEmpty
|
||||||
} else if !t.raw && t.gutterReverse || t.raw && t.gutterRawReverse {
|
} else if !t.raw && t.gutterReverse || t.raw && t.gutterRawReverse {
|
||||||
color = tui.ColCursorEmpty
|
if alt {
|
||||||
|
color = tui.ColAltCursorEmpty
|
||||||
|
} else {
|
||||||
|
color = tui.ColCursorEmpty
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
color = tui.ColCursorEmptyChar
|
if alt {
|
||||||
|
color = tui.ColAltCursorEmptyChar
|
||||||
|
} else {
|
||||||
|
color = tui.ColCursorEmptyChar
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gutter := t.pointerEmpty
|
gutter := t.pointerEmpty
|
||||||
if t.raw {
|
if t.raw {
|
||||||
@@ -3220,7 +3228,7 @@ func (t *Terminal) gutter(current bool) {
|
|||||||
|
|
||||||
func (t *Terminal) renderGapLine(line int, barRange [2]int, drawLine bool) {
|
func (t *Terminal) renderGapLine(line int, barRange [2]int, drawLine bool) {
|
||||||
t.move(line, 0, false)
|
t.move(line, 0, false)
|
||||||
t.gutter(false)
|
t.gutter(false, false)
|
||||||
t.window.Print(t.markerEmpty)
|
t.window.Print(t.markerEmpty)
|
||||||
x := t.pointerLen + t.markerLen
|
x := t.pointerLen + t.markerLen
|
||||||
|
|
||||||
@@ -3394,7 +3402,7 @@ func (t *Terminal) printItem(result Result, line int, maxLine int, index int, cu
|
|||||||
return indentSize
|
return indentSize
|
||||||
}
|
}
|
||||||
if len(label) == 0 {
|
if len(label) == 0 {
|
||||||
t.gutter(true)
|
t.gutter(true, false)
|
||||||
} else {
|
} else {
|
||||||
t.window.CPrint(tui.ColCurrentCursor, label)
|
t.window.CPrint(tui.ColCurrentCursor, label)
|
||||||
}
|
}
|
||||||
@@ -3416,7 +3424,7 @@ func (t *Terminal) printItem(result Result, line int, maxLine int, index int, cu
|
|||||||
return indentSize
|
return indentSize
|
||||||
}
|
}
|
||||||
if len(label) == 0 {
|
if len(label) == 0 {
|
||||||
t.gutter(false)
|
t.gutter(false, index%2 == 1)
|
||||||
} else {
|
} else {
|
||||||
t.window.CPrint(tui.ColCursor, label)
|
t.window.CPrint(tui.ColCursor, label)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -456,6 +456,7 @@ type ColorTheme struct {
|
|||||||
PreviewBg ColorAttr
|
PreviewBg ColorAttr
|
||||||
DarkBg ColorAttr
|
DarkBg ColorAttr
|
||||||
Gutter ColorAttr
|
Gutter ColorAttr
|
||||||
|
AltGutter ColorAttr
|
||||||
Prompt ColorAttr
|
Prompt ColorAttr
|
||||||
InputBg ColorAttr
|
InputBg ColorAttr
|
||||||
InputBorder ColorAttr
|
InputBorder ColorAttr
|
||||||
@@ -826,6 +827,8 @@ var (
|
|||||||
ColCursor ColorPair
|
ColCursor ColorPair
|
||||||
ColCursorEmpty ColorPair
|
ColCursorEmpty ColorPair
|
||||||
ColCursorEmptyChar ColorPair
|
ColCursorEmptyChar ColorPair
|
||||||
|
ColAltCursorEmpty ColorPair
|
||||||
|
ColAltCursorEmptyChar ColorPair
|
||||||
ColMarker ColorPair
|
ColMarker ColorPair
|
||||||
ColSelected ColorPair
|
ColSelected ColorPair
|
||||||
ColSelectedMatch ColorPair
|
ColSelectedMatch ColorPair
|
||||||
@@ -891,6 +894,7 @@ func init() {
|
|||||||
PreviewFg: defaultColor,
|
PreviewFg: defaultColor,
|
||||||
PreviewBg: defaultColor,
|
PreviewBg: defaultColor,
|
||||||
Gutter: undefined,
|
Gutter: undefined,
|
||||||
|
AltGutter: undefined,
|
||||||
PreviewBorder: defaultColor,
|
PreviewBorder: defaultColor,
|
||||||
PreviewScrollbar: defaultColor,
|
PreviewScrollbar: defaultColor,
|
||||||
PreviewLabel: defaultColor,
|
PreviewLabel: defaultColor,
|
||||||
@@ -943,6 +947,7 @@ func init() {
|
|||||||
PreviewFg: undefined,
|
PreviewFg: undefined,
|
||||||
PreviewBg: undefined,
|
PreviewBg: undefined,
|
||||||
Gutter: undefined,
|
Gutter: undefined,
|
||||||
|
AltGutter: undefined,
|
||||||
PreviewBorder: undefined,
|
PreviewBorder: undefined,
|
||||||
PreviewScrollbar: undefined,
|
PreviewScrollbar: undefined,
|
||||||
PreviewLabel: undefined,
|
PreviewLabel: undefined,
|
||||||
@@ -991,6 +996,7 @@ func init() {
|
|||||||
PreviewFg: undefined,
|
PreviewFg: undefined,
|
||||||
PreviewBg: undefined,
|
PreviewBg: undefined,
|
||||||
Gutter: undefined,
|
Gutter: undefined,
|
||||||
|
AltGutter: undefined,
|
||||||
PreviewBorder: undefined,
|
PreviewBorder: undefined,
|
||||||
PreviewScrollbar: undefined,
|
PreviewScrollbar: undefined,
|
||||||
PreviewLabel: undefined,
|
PreviewLabel: undefined,
|
||||||
@@ -1041,6 +1047,7 @@ func init() {
|
|||||||
PreviewFg: undefined,
|
PreviewFg: undefined,
|
||||||
PreviewBg: undefined,
|
PreviewBg: undefined,
|
||||||
Gutter: undefined,
|
Gutter: undefined,
|
||||||
|
AltGutter: undefined,
|
||||||
PreviewBorder: undefined,
|
PreviewBorder: undefined,
|
||||||
PreviewScrollbar: undefined,
|
PreviewScrollbar: undefined,
|
||||||
PreviewLabel: undefined,
|
PreviewLabel: undefined,
|
||||||
@@ -1091,6 +1098,7 @@ func init() {
|
|||||||
PreviewFg: undefined,
|
PreviewFg: undefined,
|
||||||
PreviewBg: undefined,
|
PreviewBg: undefined,
|
||||||
Gutter: undefined,
|
Gutter: undefined,
|
||||||
|
AltGutter: undefined,
|
||||||
PreviewBorder: undefined,
|
PreviewBorder: undefined,
|
||||||
PreviewScrollbar: undefined,
|
PreviewScrollbar: undefined,
|
||||||
PreviewLabel: undefined,
|
PreviewLabel: undefined,
|
||||||
@@ -1208,6 +1216,7 @@ func InitTheme(theme *ColorTheme, baseTheme *ColorTheme, boldify bool, forceBlac
|
|||||||
gutter.Attr = Dim
|
gutter.Attr = Dim
|
||||||
}
|
}
|
||||||
theme.Gutter = o(theme.DarkBg, gutter)
|
theme.Gutter = o(theme.DarkBg, gutter)
|
||||||
|
theme.AltGutter = o(theme.Gutter, theme.AltGutter)
|
||||||
theme.PreviewFg = o(theme.Fg, theme.PreviewFg)
|
theme.PreviewFg = o(theme.Fg, theme.PreviewFg)
|
||||||
theme.PreviewBg = o(theme.Bg, theme.PreviewBg)
|
theme.PreviewBg = o(theme.Bg, theme.PreviewBg)
|
||||||
theme.PreviewLabel = o(theme.BorderLabel, theme.PreviewLabel)
|
theme.PreviewLabel = o(theme.BorderLabel, theme.PreviewLabel)
|
||||||
@@ -1277,6 +1286,8 @@ func initPalette(theme *ColorTheme) {
|
|||||||
ColCursor = pair(theme.Cursor, theme.Gutter)
|
ColCursor = pair(theme.Cursor, theme.Gutter)
|
||||||
ColCursorEmpty = pair(blank, theme.Gutter)
|
ColCursorEmpty = pair(blank, theme.Gutter)
|
||||||
ColCursorEmptyChar = pair(theme.Gutter, theme.ListBg)
|
ColCursorEmptyChar = pair(theme.Gutter, theme.ListBg)
|
||||||
|
ColAltCursorEmpty = pair(blank, theme.AltGutter)
|
||||||
|
ColAltCursorEmptyChar = pair(theme.AltGutter, theme.ListBg)
|
||||||
if theme.SelectedBg.Color != theme.ListBg.Color {
|
if theme.SelectedBg.Color != theme.ListBg.Color {
|
||||||
ColMarker = pair(theme.Marker, theme.SelectedBg)
|
ColMarker = pair(theme.Marker, theme.SelectedBg)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -462,6 +462,84 @@ class TestZsh < TestBase
|
|||||||
tmux.send_keys 'C-c'
|
tmux.send_keys 'C-c'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Helper function to run test with Perl and again with Awk
|
||||||
|
def self.test_perl_and_awk(name, &block)
|
||||||
|
define_method("test_#{name}") do
|
||||||
|
instance_eval(&block)
|
||||||
|
end
|
||||||
|
|
||||||
|
define_method("test_#{name}_awk") do
|
||||||
|
tmux.send_keys "unset 'commands[perl]'", :Enter
|
||||||
|
tmux.prepare
|
||||||
|
# Verify perl is actually unset (0 = not found)
|
||||||
|
tmux.send_keys 'echo ${+commands[perl]}', :Enter
|
||||||
|
tmux.until { |lines| assert_equal '0', lines[-1] }
|
||||||
|
tmux.prepare
|
||||||
|
instance_eval(&block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def prepare_ctrl_r_test
|
||||||
|
tmux.send_keys ':', :Enter
|
||||||
|
tmux.send_keys 'echo match-collision', :Enter
|
||||||
|
tmux.prepare
|
||||||
|
tmux.send_keys 'echo "line 1', :Enter, '2 line 2"', :Enter
|
||||||
|
tmux.prepare
|
||||||
|
tmux.send_keys 'echo "foo', :Enter, 'bar"', :Enter
|
||||||
|
tmux.prepare
|
||||||
|
tmux.send_keys 'echo "bar', :Enter, 'foo"', :Enter
|
||||||
|
tmux.prepare
|
||||||
|
tmux.send_keys 'echo "trailing_space "', :Enter
|
||||||
|
tmux.prepare
|
||||||
|
tmux.send_keys 'cat <<EOF | wc -c', :Enter, 'qux thud', :Enter, 'EOF', :Enter
|
||||||
|
tmux.prepare
|
||||||
|
tmux.send_keys 'C-l', 'C-r'
|
||||||
|
end
|
||||||
|
|
||||||
|
test_perl_and_awk 'ctrl_r_accept_or_print_query' do
|
||||||
|
set_var('FZF_CTRL_R_OPTS', '--bind enter:accept-or-print-query')
|
||||||
|
prepare_ctrl_r_test
|
||||||
|
tmux.until { |lines| assert_operator lines.match_count, :>, 0 }
|
||||||
|
tmux.send_keys '1 foobar'
|
||||||
|
tmux.until { |lines| assert_equal 0, lines.match_count }
|
||||||
|
tmux.send_keys :Enter
|
||||||
|
tmux.until { |lines| assert_equal '1 foobar', lines[-1] }
|
||||||
|
end
|
||||||
|
|
||||||
|
test_perl_and_awk 'ctrl_r_multiline_index_collision' do
|
||||||
|
# Leading number in multi-line history content is not confused with index
|
||||||
|
prepare_ctrl_r_test
|
||||||
|
tmux.send_keys "'line 1"
|
||||||
|
tmux.until { |lines| assert_equal 1, lines.match_count }
|
||||||
|
tmux.send_keys :Enter
|
||||||
|
tmux.until do |lines|
|
||||||
|
assert_equal ['echo "line 1', '2 line 2"'], lines[-2..]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test_perl_and_awk 'ctrl_r_multi_selection' do
|
||||||
|
prepare_ctrl_r_test
|
||||||
|
tmux.until { |lines| assert_operator lines.match_count, :>, 0 }
|
||||||
|
tmux.send_keys :BTab, :BTab, :BTab
|
||||||
|
tmux.until { |lines| assert_includes lines[-2], '(3)' }
|
||||||
|
tmux.send_keys :Enter
|
||||||
|
tmux.until do |lines|
|
||||||
|
assert_equal ['cat <<EOF | wc -c', 'qux thud', 'EOF', 'echo "trailing_space "', 'echo "bar', 'foo"'], lines[-6..]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test_perl_and_awk 'ctrl_r_no_multi_selection' do
|
||||||
|
set_var('FZF_CTRL_R_OPTS', '--no-multi')
|
||||||
|
prepare_ctrl_r_test
|
||||||
|
tmux.until { |lines| assert_operator lines.match_count, :>, 0 }
|
||||||
|
tmux.send_keys :BTab, :BTab, :BTab
|
||||||
|
tmux.until { |lines| refute_includes lines[-2], '(3)' }
|
||||||
|
tmux.send_keys :Enter
|
||||||
|
tmux.until do |lines|
|
||||||
|
assert_equal ['cat <<EOF | wc -c', 'qux thud', 'EOF'], lines[-3..]
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class TestFish < TestBase
|
class TestFish < TestBase
|
||||||
|
|||||||
Reference in New Issue
Block a user