diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d07b93b..e67bf165 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,16 @@ CHANGELOG ========= +0.22.1 +------ +- Support preview scroll offset relative to window height + ```sh + git grep --line-number '' | + fzf --delimiter : \ + --preview 'bat --style=numbers --color=always --highlight-line {2} {1}' \ + --preview-window +{2}-/2 + ``` + 0.22.0 ------ - Added more options for `--bind` diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index becde6af..6408a4bb 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -394,7 +394,8 @@ execute the command in the background. window. \fBSCROLL\fR can be either a numeric integer or a single-field index expression that refers to a numeric integer. The optional \fB-OFFSET\fR part is for adjusting the base offset so that you can see the text above it. It should -be given as a numeric integer. +be given as a numeric integer (\fB-INTEGER\fR), or as a denominator form +(\fB-/INTEGER\fR) for specifying a fraction of the preview window height. .RS .B POSITION: (default: right) @@ -411,9 +412,15 @@ e.g. fzf --preview="file {}" --preview-window=down:1 # Initial scroll offset is set to the line number of each line of - # git grep output *minus* 5 lines + # git grep output *minus* 5 lines (-5) git grep --line-number '' | - fzf --delimiter : --preview 'nl {1}' --preview-window +{2}-5\fR + fzf --delimiter : --preview 'nl {1}' --preview-window +{2}-5 + + # Preview with bat, matching line in the middle of the window (-/2) + git grep --line-number '' | + fzf --delimiter : \\ + --preview 'bat --style=numbers --color=always --highlight-line {2} {1}' \\ + --preview-window +{2}-/2\fR .RE .SS Scripting diff --git a/src/options.go b/src/options.go index 699e8a55..a916e806 100644 --- a/src/options.go +++ b/src/options.go @@ -995,7 +995,7 @@ func parsePreviewWindow(opts *previewOpts, input string) { tokens := strings.Split(input, ":") sizeRegex := regexp.MustCompile("^[1-9][0-9]*%?$") - offsetRegex := regexp.MustCompile("^\\+([0-9]+|{-?[0-9]+})(-[0-9]+)?$") + offsetRegex := regexp.MustCompile("^\\+([0-9]+|{-?[0-9]+})(-[0-9]+|-/[1-9][0-9]*)?$") for _, token := range tokens { switch token { case "": diff --git a/src/terminal.go b/src/terminal.go index a7e9e9b2..2fa13984 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -1374,7 +1374,7 @@ func atopi(s string) int { return n } -func (t *Terminal) evaluateScrollOffset(list []*Item) int { +func (t *Terminal) evaluateScrollOffset(list []*Item, height int) int { offsetExpr := t.replacePlaceholder(t.preview.scroll, false, "", list) nums := strings.Split(offsetExpr, "-") switch len(nums) { @@ -1387,6 +1387,13 @@ func (t *Terminal) evaluateScrollOffset(list []*Item) int { } else if len(nums) == 1 { return base - 1 } + if nums[1][0] == '/' { + denom := atopi(nums[1][1:]) + if denom == 0 { + return base + } + return base - height/denom + } return base - atopi(nums[1]) - 1 default: return 0 @@ -1676,11 +1683,12 @@ func (t *Terminal) Loop() { // We don't display preview window if no match if items[0] != nil { command := t.replacePlaceholder(commandTemplate, false, string(t.Input()), items) - offset := t.evaluateScrollOffset(items) + height := t.pwindow.Height() + offset := t.evaluateScrollOffset(items, height) cmd := util.ExecCommand(command, true) if t.pwindow != nil { env := os.Environ() - lines := fmt.Sprintf("LINES=%d", t.pwindow.Height()) + lines := fmt.Sprintf("LINES=%d", height) columns := fmt.Sprintf("COLUMNS=%d", t.pwindow.Width()) env = append(env, lines) env = append(env, "FZF_PREVIEW_"+lines)