From 2ccdf21a1fa0ce64123fe89e1b7931240420e8e6 Mon Sep 17 00:00:00 2001 From: Junegunn Choi <junegunn.c@gmail.com> Date: Wed, 2 Mar 2016 03:06:21 +0900 Subject: [PATCH] Add --hscroll-off=COL option Close #513 --- man/man1/fzf.1 | 7 ++++++- src/options.go | 12 ++++++++++++ src/terminal.go | 9 +++++---- src/util/util.go | 8 ++++++++ test/test_go.rb | 12 ++++++++++++ 5 files changed, 43 insertions(+), 5 deletions(-) diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index ef48770a..1a99a548 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -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 "Feb 2016" "fzf 0.11.3" "fzf - a command-line fuzzy finder" +.TH fzf 1 "Mar 2016" "fzf 0.11.4" "fzf - a command-line fuzzy finder" .SH NAME fzf - a command-line fuzzy finder @@ -175,6 +175,11 @@ Enable cyclic scroll .B "--no-hscroll" Disable horizontal scroll .TP +.BI "--hscroll-off=" "COL" +Number of screen columns to keep to the right of the highlighted substring +(default: 10). Setting it to a large value will cause the text to be positioned +on the center of the screen. +.TP .B "--inline-info" Display finder info inline with the query .TP diff --git a/src/options.go b/src/options.go index 723c7fc6..dfd9a1b6 100644 --- a/src/options.go +++ b/src/options.go @@ -42,6 +42,8 @@ const usage = `usage: fzf [options] --tabstop=SPACES Number of spaces for a tab character (default: 8) --cycle Enable cyclic scroll --no-hscroll Disable horizontal scroll + --hscroll-off=COL Number of screen columns to keep to the right of the + highlighted substring (default: 10) --inline-info Display finder info inline with the query --prompt=STR Input prompt (default: '> ') --bind=KEYBINDS Custom key bindings. Refer to the man page. @@ -108,6 +110,7 @@ type Options struct { Reverse bool Cycle bool Hscroll bool + HscrollOff int InlineInfo bool Prompt string Query string @@ -155,6 +158,7 @@ func defaultOptions() *Options { Reverse: false, Cycle: false, Hscroll: true, + HscrollOff: 10, InlineInfo: false, Prompt: "> ", Query: "", @@ -795,6 +799,8 @@ func parseOptions(opts *Options, allArgs []string) { opts.Hscroll = true case "--no-hscroll": opts.Hscroll = false + case "--hscroll-off": + opts.HscrollOff = nextInt(allArgs, &i, "hscroll offset required") case "--inline-info": opts.InlineInfo = true case "--no-inline-info": @@ -884,6 +890,8 @@ func parseOptions(opts *Options, allArgs []string) { opts.Margin = parseMargin(value) } else if match, value := optString(arg, "--tabstop="); match { opts.Tabstop = atoi(value) + } else if match, value := optString(arg, "--hscroll-off="); match { + opts.HscrollOff = atoi(value) } else { errorExit("unknown option: " + arg) } @@ -894,6 +902,10 @@ func parseOptions(opts *Options, allArgs []string) { errorExit("header lines must be a non-negative integer") } + if opts.HscrollOff < 0 { + errorExit("hscroll offset must be a non-negative integer") + } + if opts.Tabstop < 1 { errorExit("tab stop must be a positive integer") } diff --git a/src/terminal.go b/src/terminal.go index 3c6f47c6..d95cfad3 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -26,6 +26,7 @@ type Terminal struct { prompt string reverse bool hscroll bool + hscrollOff int cx int cy int offset int @@ -210,6 +211,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal { prompt: opts.Prompt, reverse: opts.Reverse, hscroll: opts.Hscroll, + hscrollOff: opts.HscrollOff, cx: len(input), cy: 0, offset: 0, @@ -556,11 +558,9 @@ func trimLeft(runes []rune, width int) ([]rune, int32) { } func (t *Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int, current bool) { - var maxe int32 + var maxe int for _, offset := range item.offsets { - if offset[1] > maxe { - maxe = offset[1] - } + maxe = util.Max(maxe, int(offset[1])) } // Overflow @@ -568,6 +568,7 @@ func (t *Terminal) printHighlighted(item *Item, bold bool, col1 int, col2 int, c copy(text, item.text) offsets := item.colorOffsets(col2, bold, current) maxWidth := C.MaxX() - 3 - t.marginInt[1] - t.marginInt[3] + maxe = util.Constrain(maxe+util.Min(maxWidth/2-2, t.hscrollOff), 0, len(text)) fullWidth := displayWidth(text) if fullWidth > maxWidth { if t.hscroll { diff --git a/src/util/util.go b/src/util/util.go index ab9e7664..4f3d409d 100644 --- a/src/util/util.go +++ b/src/util/util.go @@ -21,6 +21,14 @@ func Max(first int, items ...int) int { return max } +// Min returns the smallest integer +func Min(first int, second int) int { + if first <= second { + return first + } + return second +} + // Min32 returns the smallest 32-bit integer func Min32(first int32, second int32) int32 { if first <= second { diff --git a/test/test_go.rb b/test/test_go.rb index 7a2d0039..28cb8339 100644 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -1137,6 +1137,18 @@ class TestGoFZF < TestBase `seq 10 | #{FZF} -f '1 | !1'`.lines.map(&:chomp) end + def test_hscroll_off + writelines tempname, ['=' * 10000 + '0123456789'] + [0, 3, 6].each do |off| + tmux.prepare + tmux.send_keys "#{FZF} --hscroll-off=#{off} -q 0 < #{tempname}", :Enter + tmux.until { |lines| lines[-3].end_with?((0..off).to_a.join + '..') } + tmux.send_keys '9' + tmux.until { |lines| lines[-3].end_with? '789' } + tmux.send_keys :Enter + end + end + private def writelines path, lines File.unlink path while File.exists? path -- GitLab