mirror of
https://github.com/junegunn/fzf.git
synced 2026-08-15 20:28:04 +08:00
Add --preview-wrap-sign
This commit is contained in:
@@ -32,6 +32,8 @@ CHANGELOG
|
|||||||
# In the preview window
|
# In the preview window
|
||||||
fzf --preview "printf '\e[4:3;58;2;255;0;0mRed curly underline\e[0m\n'"
|
fzf --preview "printf '\e[4:3;58;2;255;0;0mRed curly underline\e[0m\n'"
|
||||||
```
|
```
|
||||||
|
- Added `--preview-wrap-sign` to set a different wrap indicator for the preview
|
||||||
|
window
|
||||||
- Added `alt-gutter` color option (#4602) (@hedgieinsocks)
|
- Added `alt-gutter` color option (#4602) (@hedgieinsocks)
|
||||||
- Added fish completion support (#4605) (@lalvarezt)
|
- Added fish completion support (#4605) (@lalvarezt)
|
||||||
- zsh: Handle multi-line history selection (#4595) (@LangLangBart)
|
- zsh: Handle multi-line history selection (#4595) (@LangLangBart)
|
||||||
|
|||||||
@@ -919,6 +919,11 @@ Should be used with one of the following \fB\-\-preview\-window\fR options.
|
|||||||
.B * border\-bottom
|
.B * border\-bottom
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI "\-\-preview\-wrap\-sign" =INDICATOR
|
||||||
|
Indicator for wrapped lines in the preview window. If not set, the value of
|
||||||
|
\fB\-\-wrap\-sign\fR is used.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BI "\-\-preview\-label\-pos" [=N[:top|bottom]]
|
.BI "\-\-preview\-label\-pos" [=N[:top|bottom]]
|
||||||
Position of the border label on the border line of the preview window. Specify
|
Position of the border label on the border line of the preview window. Specify
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ _fzf_opts_completion() {
|
|||||||
--with-shell
|
--with-shell
|
||||||
--wrap
|
--wrap
|
||||||
--wrap-sign
|
--wrap-sign
|
||||||
|
--preview-wrap-sign
|
||||||
--zsh
|
--zsh
|
||||||
-0 --exit-0
|
-0 --exit-0
|
||||||
-1 --select-1
|
-1 --select-1
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ Usage: fzf [options]
|
|||||||
--preview-label=LABEL
|
--preview-label=LABEL
|
||||||
--preview-label-pos=N Same as --border-label and --border-label-pos,
|
--preview-label-pos=N Same as --border-label and --border-label-pos,
|
||||||
but for preview window
|
but for preview window
|
||||||
|
--preview-wrap-sign=STR Indicator for wrapped lines in the preview window
|
||||||
|
|
||||||
HEADER
|
HEADER
|
||||||
--header=STR String to print as header
|
--header=STR String to print as header
|
||||||
@@ -608,6 +609,7 @@ type Options struct {
|
|||||||
Wrap bool
|
Wrap bool
|
||||||
WrapWord bool
|
WrapWord bool
|
||||||
WrapSign *string
|
WrapSign *string
|
||||||
|
PreviewWrapSign *string
|
||||||
MultiLine bool
|
MultiLine bool
|
||||||
CursorLine bool
|
CursorLine bool
|
||||||
KeepRight bool
|
KeepRight bool
|
||||||
@@ -3113,6 +3115,12 @@ func parseOptions(index *int, opts *Options, allArgs []string) error {
|
|||||||
if opts.Preview.border, err = parseBorder(arg, !hasArg); err != nil {
|
if opts.Preview.border, err = parseBorder(arg, !hasArg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
case "--preview-wrap-sign":
|
||||||
|
str, err := nextString("preview wrap sign required")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
opts.PreviewWrapSign = &str
|
||||||
case "--height":
|
case "--height":
|
||||||
str, err := nextString("height required: [~]HEIGHT[%]")
|
str, err := nextString("height required: [~]HEIGHT[%]")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -464,6 +464,50 @@ func TestPreviewOpts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPreviewWrapSign(t *testing.T) {
|
||||||
|
// Default: no preview wrap sign override
|
||||||
|
opts := optsFor()
|
||||||
|
if opts.PreviewWrapSign != nil {
|
||||||
|
t.Errorf("expected nil PreviewWrapSign, got %v", *opts.PreviewWrapSign)
|
||||||
|
}
|
||||||
|
|
||||||
|
// --preview-wrap-sign sets PreviewWrapSign
|
||||||
|
opts = optsFor("--preview-wrap-sign", ">> ")
|
||||||
|
if opts.PreviewWrapSign == nil || *opts.PreviewWrapSign != ">> " {
|
||||||
|
t.Errorf("expected '>> ', got %v", opts.PreviewWrapSign)
|
||||||
|
}
|
||||||
|
|
||||||
|
// --preview-wrap-sign is independent of --wrap-sign
|
||||||
|
opts = optsFor("--wrap-sign", "| ", "--preview-wrap-sign", ">> ")
|
||||||
|
if opts.WrapSign == nil || *opts.WrapSign != "| " {
|
||||||
|
t.Errorf("expected WrapSign '| ', got %v", opts.WrapSign)
|
||||||
|
}
|
||||||
|
if opts.PreviewWrapSign == nil || *opts.PreviewWrapSign != ">> " {
|
||||||
|
t.Errorf("expected PreviewWrapSign '>> ', got %v", opts.PreviewWrapSign)
|
||||||
|
}
|
||||||
|
|
||||||
|
// --preview-wrap-sign without --wrap-sign
|
||||||
|
opts = optsFor("--preview-wrap-sign", "→ ")
|
||||||
|
if opts.WrapSign != nil {
|
||||||
|
t.Errorf("expected nil WrapSign, got %v", *opts.WrapSign)
|
||||||
|
}
|
||||||
|
if opts.PreviewWrapSign == nil || *opts.PreviewWrapSign != "→ " {
|
||||||
|
t.Errorf("expected PreviewWrapSign '→ ', got %v", opts.PreviewWrapSign)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last --preview-wrap-sign wins
|
||||||
|
opts = optsFor("--preview-wrap-sign", "A ", "--preview-wrap-sign", "B ")
|
||||||
|
if opts.PreviewWrapSign == nil || *opts.PreviewWrapSign != "B " {
|
||||||
|
t.Errorf("expected PreviewWrapSign 'B ', got %v", opts.PreviewWrapSign)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty string is allowed
|
||||||
|
opts = optsFor("--preview-wrap-sign", "")
|
||||||
|
if opts.PreviewWrapSign == nil || *opts.PreviewWrapSign != "" {
|
||||||
|
t.Errorf("expected empty PreviewWrapSign, got %v", opts.PreviewWrapSign)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAdditiveExpect(t *testing.T) {
|
func TestAdditiveExpect(t *testing.T) {
|
||||||
opts := optsFor("--expect=a", "--expect", "b", "--expect=c")
|
opts := optsFor("--expect=a", "--expect", "b", "--expect=c")
|
||||||
if len(opts.Expect) != 3 {
|
if len(opts.Expect) != 3 {
|
||||||
|
|||||||
+14
-7
@@ -253,6 +253,8 @@ type Terminal struct {
|
|||||||
wrapWord bool
|
wrapWord bool
|
||||||
wrapSign string
|
wrapSign string
|
||||||
wrapSignWidth int
|
wrapSignWidth int
|
||||||
|
previewWrapSign string
|
||||||
|
previewWrapSignWidth int
|
||||||
ghost string
|
ghost string
|
||||||
separator labelPrinter
|
separator labelPrinter
|
||||||
separatorLen int
|
separatorLen int
|
||||||
@@ -1251,6 +1253,11 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
|
|||||||
t.wrapSign = *opts.WrapSign
|
t.wrapSign = *opts.WrapSign
|
||||||
}
|
}
|
||||||
t.wrapSign, t.wrapSignWidth = t.processTabsStr(t.wrapSign, 0)
|
t.wrapSign, t.wrapSignWidth = t.processTabsStr(t.wrapSign, 0)
|
||||||
|
t.previewWrapSign = t.wrapSign
|
||||||
|
t.previewWrapSignWidth = t.wrapSignWidth
|
||||||
|
if opts.PreviewWrapSign != nil {
|
||||||
|
t.previewWrapSign, t.previewWrapSignWidth = t.processTabsStr(*opts.PreviewWrapSign, 0)
|
||||||
|
}
|
||||||
if opts.Scrollbar == nil {
|
if opts.Scrollbar == nil {
|
||||||
if t.unicode && t.borderWidth == 1 {
|
if t.unicode && t.borderWidth == 1 {
|
||||||
t.scrollbar = "│"
|
t.scrollbar = "│"
|
||||||
@@ -2312,7 +2319,7 @@ func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
|
|||||||
pwidth -= 1
|
pwidth -= 1
|
||||||
}
|
}
|
||||||
t.pwindow = t.tui.NewWindow(y, x, pwidth, pheight, tui.WindowPreview, noBorder, true)
|
t.pwindow = t.tui.NewWindow(y, x, pwidth, pheight, tui.WindowPreview, noBorder, true)
|
||||||
t.pwindow.SetWrapSign(t.wrapSign, t.wrapSignWidth)
|
t.pwindow.SetWrapSign(t.previewWrapSign, t.previewWrapSignWidth)
|
||||||
if !hadPreviewWindow {
|
if !hadPreviewWindow {
|
||||||
t.pwindow.Erase()
|
t.pwindow.Erase()
|
||||||
}
|
}
|
||||||
@@ -4130,14 +4137,14 @@ func (t *Terminal) previewLineHeight(line string, maxWidth int) int {
|
|||||||
// For word-wrap mode, count the sub-lines produced by word wrapping.
|
// For word-wrap mode, count the sub-lines produced by word wrapping.
|
||||||
// Each sub-line may still char-wrap if it contains a word longer than the width.
|
// Each sub-line may still char-wrap if it contains a word longer than the width.
|
||||||
if t.activePreviewOpts.wrapWord {
|
if t.activePreviewOpts.wrapWord {
|
||||||
subLines := t.wordWrapAnsiLine(line, maxWidth, t.wrapSignWidth)
|
subLines := t.wordWrapAnsiLine(line, maxWidth, t.previewWrapSignWidth)
|
||||||
total := 0
|
total := 0
|
||||||
for i, sub := range subLines {
|
for i, sub := range subLines {
|
||||||
prefixWidth := 0
|
prefixWidth := 0
|
||||||
cols := maxWidth
|
cols := maxWidth
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
prefixWidth = t.wrapSignWidth
|
prefixWidth = t.previewWrapSignWidth
|
||||||
cols -= t.wrapSignWidth
|
cols -= t.previewWrapSignWidth
|
||||||
}
|
}
|
||||||
w := t.ansiLineWidth(sub, prefixWidth)
|
w := t.ansiLineWidth(sub, prefixWidth)
|
||||||
if cols <= 0 {
|
if cols <= 0 {
|
||||||
@@ -4154,7 +4161,7 @@ func (t *Terminal) previewLineHeight(line string, maxWidth int) int {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
remaining := w - maxWidth
|
remaining := w - maxWidth
|
||||||
contWidth := max(1, maxWidth-t.wrapSignWidth)
|
contWidth := max(1, maxWidth-t.previewWrapSignWidth)
|
||||||
return 1 + (remaining+contWidth-1)/contWidth
|
return 1 + (remaining+contWidth-1)/contWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4333,7 +4340,7 @@ Loop:
|
|||||||
// Pre-split line into sub-lines for word wrapping
|
// Pre-split line into sub-lines for word wrapping
|
||||||
var subLines []string
|
var subLines []string
|
||||||
if t.activePreviewOpts.wrapWord {
|
if t.activePreviewOpts.wrapWord {
|
||||||
subLines = t.wordWrapAnsiLine(line, maxWidth, t.wrapSignWidth)
|
subLines = t.wordWrapAnsiLine(line, maxWidth, t.previewWrapSignWidth)
|
||||||
} else {
|
} else {
|
||||||
subLines = []string{line}
|
subLines = []string{line}
|
||||||
}
|
}
|
||||||
@@ -4341,7 +4348,7 @@ Loop:
|
|||||||
var fillRet tui.FillReturn
|
var fillRet tui.FillReturn
|
||||||
wrap := t.activePreviewOpts.wrap
|
wrap := t.activePreviewOpts.wrap
|
||||||
printWrapSign := func() {
|
printWrapSign := func() {
|
||||||
if t.pwindow.CFill(tui.ColPreview.Fg(), tui.ColPreview.Bg(), -1, tui.Dim, t.wrapSign) == tui.FillNextLine {
|
if t.pwindow.CFill(tui.ColPreview.Fg(), tui.ColPreview.Bg(), -1, tui.Dim, t.previewWrapSign) == tui.FillNextLine {
|
||||||
t.pwindow.Move(t.pwindow.Y()-1, t.pwindow.Width())
|
t.pwindow.Move(t.pwindow.Y()-1, t.pwindow.Width())
|
||||||
}
|
}
|
||||||
fillRet = tui.FillContinue
|
fillRet = tui.FillContinue
|
||||||
|
|||||||
Reference in New Issue
Block a user