Skip to content

Commit

Permalink
Add preview window option for setting the initial scroll offset
Browse files Browse the repository at this point in the history
Close junegunn#1057
Close junegunn#2120

  # Initial scroll offset is set to the line number of each line of
  # git grep output *minus* 5 lines
  git grep --line-number '' |
    fzf --delimiter : --preview 'nl {1}' --preview-window +{2}-5
  • Loading branch information
junegunn committed Jul 26, 2020
1 parent c0a83b2 commit 0f9cb55
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 17 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ CHANGELOG
# Preview window hidden by default, it appears when you first hit '?'
fzf --bind '?:preview:cat {}' --preview-window hidden
```
- Added preview window option for setting the initial scroll offset
```sh
# Initial scroll offset is set to the line number of each line of
# git grep output *minus* 5 lines
git grep --line-number '' |
fzf --delimiter : --preview 'nl {1}' --preview-window +{2}-5
```
- Added support for ANSI colors in `--prompt` string
- Vim plugin
- `tmux` layout option for using fzf-tmux
Expand Down
21 changes: 17 additions & 4 deletions man/man1/fzf.1
Original file line number Diff line number Diff line change
Expand Up @@ -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
THE SOFTWARE.
..
.TH fzf 1 "Jun 2020" "fzf 0.22.0" "fzf - a command-line fuzzy finder"
.TH fzf 1 "Jul 2020" "fzf 0.22.0" "fzf - a command-line fuzzy finder"

.SH NAME
fzf - a command-line fuzzy finder
Expand Down Expand Up @@ -381,7 +381,7 @@ Preview window will be updated even when there is no match for the current
query if any of the placeholder expressions evaluates to a non-empty string.
.RE
.TP
.BI "--preview-window=" "[POSITION][:SIZE[%]][:noborder][:wrap][:hidden]"
.BI "--preview-window=" "[POSITION][:SIZE[%]][:noborder][:wrap][:hidden][:+SCROLL[-OFFSET]]"
Determines the layout of the preview window. If the argument contains
\fB:hidden\fR, the preview window will be hidden by default until
\fBtoggle-preview\fR action is triggered. Long lines are truncated by default.
Expand All @@ -390,6 +390,12 @@ Line wrap can be enabled with \fB:wrap\fR flag.
If size is given as 0, preview window will not be visible, but fzf will still
execute the command in the background.

\fB+SCROLL[-OFFSET]\fR determines the initial scroll offset of the preview
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.

.RS
.B POSITION: (default: right)
\fBup
Expand All @@ -400,8 +406,15 @@ execute the command in the background.

.RS
e.g.
\fBfzf --preview="head {}" --preview-window=up:30%
fzf --preview="file {}" --preview-window=down:1\fR
\fB# Non-default scroll window positions and sizes
fzf --preview="head {}" --preview-window=up:30%
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 --line-number '' |
fzf --delimiter : --preview 'nl {1}' --preview-window +{2}-5\fR

.RE
.SS Scripting
.TP
Expand Down
12 changes: 8 additions & 4 deletions src/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const usage = `usage: fzf [options]
Preview
--preview=COMMAND Command to preview highlighted line ({})
--preview-window=OPT Preview window layout (default: right:50%)
[up|down|left|right][:SIZE[%]][:wrap][:hidden]
[up|down|left|right][:SIZE[%]][:wrap][:hidden][:+SCROLL[-OFFSET]]
Scripting
-q, --query=STR Start the finder with the given query
Expand Down Expand Up @@ -159,6 +159,7 @@ type previewOpts struct {
command string
position windowPosition
size sizeSpec
scroll string
hidden bool
wrap bool
border bool
Expand Down Expand Up @@ -260,7 +261,7 @@ func defaultOptions() *Options {
ToggleSort: false,
Expect: make(map[int]string),
Keymap: make(map[int][]action),
Preview: previewOpts{"", posRight, sizeSpec{50, true}, false, false, true},
Preview: previewOpts{"", posRight, sizeSpec{50, true}, "", false, false, true},
PrintQuery: false,
ReadZero: false,
Printer: func(str string) { fmt.Println(str) },
Expand Down Expand Up @@ -994,6 +995,7 @@ func parsePreviewWindow(opts *previewOpts, input string) {

tokens := strings.Split(input, ":")
sizeRegex := regexp.MustCompile("^[0-9]+%?$")
offsetRegex := regexp.MustCompile("^\\+([0-9]+|{[0-9]+})(-[0-9]+)?$")
for _, token := range tokens {
switch token {
case "":
Expand All @@ -1016,8 +1018,10 @@ func parsePreviewWindow(opts *previewOpts, input string) {
default:
if sizeRegex.MatchString(token) {
opts.size = parseSize(token, 99, "window size")
} else if offsetRegex.MatchString(token) {
opts.scroll = token[1:]
} else {
errorExit("invalid preview window layout: " + input)
errorExit("invalid preview window option: " + token)
}
}
}
Expand Down Expand Up @@ -1270,7 +1274,7 @@ func parseOptions(opts *Options, allArgs []string) {
opts.Preview.command = ""
case "--preview-window":
parsePreviewWindow(&opts.Preview,
nextString(allArgs, &i, "preview window layout required: [up|down|left|right][:SIZE[%]][:noborder][:wrap][:hidden]"))
nextString(allArgs, &i, "preview window layout required: [up|down|left|right][:SIZE[%]][:noborder][:wrap][:hidden][:+SCROLL[-OFFSET]]"))
case "--height":
opts.Height = parseHeight(nextString(allArgs, &i, "height required: HEIGHT[%]"))
case "--min-height":
Expand Down
56 changes: 47 additions & 9 deletions src/terminal.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ type previewRequest struct {
list []*Item
}

type previewResult struct {
content string
offset int
}

func toActions(types ...actionType) []action {
actions := make([]action, len(types))
for idx, t := range types {
Expand Down Expand Up @@ -1347,6 +1352,39 @@ func cleanTemporaryFiles() {
activeTempFiles = []string{}
}

func (t *Terminal) replacePlaceholder(template string, forcePlus bool, input string, list []*Item) string {
return replacePlaceholder(
template, t.ansi, t.delimiter, t.printsep, forcePlus, input, list)
}

// Ascii to positive integer
func atopi(s string) int {
n, e := strconv.Atoi(strings.ReplaceAll(s, "'", ""))
if e != nil || n < 1 {
return 0
}
return n
}

func (t *Terminal) evaluateScrollOffset(list []*Item) int {
offsetExpr := t.replacePlaceholder(t.preview.scroll, false, "", list)
nums := strings.Split(offsetExpr, "-")
switch len(nums) {
case 0:
return 0
case 1, 2:
base := atopi(nums[0])
if base == 0 {
return 0
} else if len(nums) == 1 {
return base - 1
}
return base - atopi(nums[1]) - 1
default:
return 0
}
}

func replacePlaceholder(template string, stripAnsi bool, delimiter Delimiter, printsep string, forcePlus bool, query string, allItems []*Item) string {
current := allItems[:1]
selected := allItems[1:]
Expand Down Expand Up @@ -1445,7 +1483,7 @@ func (t *Terminal) executeCommand(template string, forcePlus bool, background bo
if !valid {
return
}
command := replacePlaceholder(template, t.ansi, t.delimiter, t.printsep, forcePlus, string(t.input), list)
command := t.replacePlaceholder(template, forcePlus, string(t.input), list)
cmd := util.ExecCommand(command, false)
if !background {
cmd.Stdin = os.Stdin
Expand Down Expand Up @@ -1629,8 +1667,8 @@ func (t *Terminal) Loop() {
})
// We don't display preview window if no match
if items[0] != nil {
command := replacePlaceholder(commandTemplate,
t.ansi, t.delimiter, t.printsep, false, string(t.Input()), items)
command := t.replacePlaceholder(commandTemplate, false, string(t.Input()), items)
offset := t.evaluateScrollOffset(items)
cmd := util.ExecCommand(command, true)
if t.pwindow != nil {
env := os.Environ()
Expand Down Expand Up @@ -1673,11 +1711,11 @@ func (t *Terminal) Loop() {
cmd.Wait()
finishChan <- true
if out.Len() > 0 || !<-updateChan {
t.reqBox.Set(reqPreviewDisplay, out.String())
t.reqBox.Set(reqPreviewDisplay, previewResult{out.String(), offset})
}
cleanTemporaryFiles()
} else {
t.reqBox.Set(reqPreviewDisplay, "")
t.reqBox.Set(reqPreviewDisplay, previewResult{"", 0})
}
}
}()
Expand Down Expand Up @@ -1751,9 +1789,10 @@ func (t *Terminal) Loop() {
return exitNoMatch
})
case reqPreviewDisplay:
t.previewer.text = value.(string)
result := value.(previewResult)
t.previewer.text = result.content
t.previewer.lines = strings.Count(t.previewer.text, "\n")
t.previewer.offset = 0
t.previewer.offset = util.Constrain(result.offset, 0, t.previewer.lines-1)
t.printPreview()
case reqPreviewRefresh:
t.printPreview()
Expand Down Expand Up @@ -2172,8 +2211,7 @@ func (t *Terminal) Loop() {
valid = !slot || query
}
if valid {
command := replacePlaceholder(a.a,
t.ansi, t.delimiter, t.printsep, false, string(t.input), list)
command := t.replacePlaceholder(a.a, false, string(t.input), list)
newCommand = &command
}
}
Expand Down
18 changes: 18 additions & 0 deletions test/test_go.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1787,6 +1787,24 @@ def test_preview_bindings_without_default_preview
tmux.until { |lines| refute_includes lines[1], '2' }
tmux.until { |lines| assert_includes lines[1], '[111]' }
end

def test_preview_scroll_begin_constant
tmux.send_keys "echo foo 123 321 | #{FZF} --preview 'seq 1000' --preview-window left:+123", :Enter
tmux.until { |lines| lines.item_count == 1 }
tmux.until { |lines| assert_match %r{123.*123/1000}, lines[1] }
end

def test_preview_scroll_begin_expr
tmux.send_keys "echo foo 123 321 | #{FZF} --preview 'seq 1000' --preview-window left:+{3}", :Enter
tmux.until { |lines| lines.item_count == 1 }
tmux.until { |lines| assert_match %r{321.*321/1000}, lines[1] }
end

def test_preview_scroll_begin_and_offset
tmux.send_keys "echo foo 123 321 | #{FZF} --preview 'seq 1000' --preview-window left:+{2}-2", :Enter
tmux.until { |lines| lines.item_count == 1 }
tmux.until { |lines| assert_match %r{121.*121/1000}, lines[1] }
end
end

module TestShell
Expand Down

0 comments on commit 0f9cb55

Please sign in to comment.