From 2022a3ad96f027e056e4fcce11fee0976db657d1 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Tue, 15 Sep 2015 19:04:53 +0900 Subject: [PATCH] Replace --header-file with --header (#346) and allow using --header and --header-lines at the same time. Close #346. --- CHANGELOG.md | 10 ++++++++++ man/man1/fzf.1 | 10 +++++----- shell/completion.bash | 4 ++-- src/core.go | 2 +- src/options.go | 26 ++++++++------------------ src/terminal.go | 36 +++++++++++++++++++++--------------- test/test_go.rb | 28 ++++++++++++++++++++++++---- 7 files changed, 71 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a337b10..f10cbca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,16 @@ CHANGELOG ========= +0.10.6 +------ + +- Replaced `--header-file` with `--header` option +- `--header` and `--header-lines` can be used together +- Changed exit status + - 0: Okay + - 1: No match + - 2: Error/Interrupted + 0.10.5 ------ diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 79df436..4147371 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -285,11 +285,11 @@ When enabled, \fBCTRL-N\fR and \fBCTRL-P\fR are automatically remapped to Maximum number of entries in the history file (default: 1000). The file is automatically truncated when the number of the lines exceeds the value. .TP -.BI "--header-file=" "FILE" -The content of the file will be printed as the sticky header. The lines in the -file are displayed in order from top to bottom regardless of \fB--reverse\fR, -and are not affected by \fB--with-nth\fR. ANSI color codes are processed even -when \fB--ansi\fR is not set. +.BI "--header=" "STR" +The given string will be printed as the sticky header. The lines are displayed +in the given order from top to bottom regardless of \fB--reverse\fR option, and +are not affected by \fB--with-nth\fR. ANSI color codes are processed even when +\fB--ansi\fR is not set. .TP .BI "--header-lines=" "N" The first N lines of the input are treated as the sticky header. When diff --git a/shell/completion.bash b/shell/completion.bash index 63de546..d7fdf26 100644 --- a/shell/completion.bash +++ b/shell/completion.bash @@ -49,7 +49,7 @@ _fzf_opts_completion() { --cycle --history --history-size - --header-file + --header --header-lines --margin" @@ -62,7 +62,7 @@ _fzf_opts_completion() { COMPREPLY=( $(compgen -W "dark light 16 bw" -- ${cur}) ) return 0 ;; - --history|--header-file) + --history) COMPREPLY=() return 0 ;; diff --git a/src/core.go b/src/core.go index 04b6eab..35d7ced 100644 --- a/src/core.go +++ b/src/core.go @@ -238,7 +238,7 @@ func Run(opts *Options) { } case EvtHeader: - terminal.UpdateHeader(value.([]string), opts.HeaderLines) + terminal.UpdateHeader(value.([]string)) case EvtSearchFin: switch val := value.(type) { diff --git a/src/options.go b/src/options.go index 47d8bb1..9d8aaa1 100644 --- a/src/options.go +++ b/src/options.go @@ -1,7 +1,6 @@ package fzf import ( - "io/ioutil" "os" "regexp" "strconv" @@ -45,7 +44,7 @@ const usage = `usage: fzf [options] --bind=KEYBINDS Custom key bindings. Refer to the man page. --history=FILE History file --history-size=N Maximum number of history entries (default: 1000) - --header-file=FILE The file whose content to be printed as header + --header=STR String to print as header --header-lines=N The first N lines of the input are treated as header Scripting @@ -604,12 +603,8 @@ func checkToggleSort(keymap map[int]actionType, str string) map[int]actionType { return keymap } -func readHeaderFile(filename string) []string { - content, err := ioutil.ReadFile(filename) - if err != nil { - errorExit("failed to read header file: " + filename) - } - return strings.Split(strings.TrimSuffix(string(content), "\n"), "\n") +func strLines(str string) []string { + return strings.Split(strings.TrimSuffix(str, "\n"), "\n") } func parseMargin(margin string) [4]string { @@ -793,16 +788,13 @@ func parseOptions(opts *Options, allArgs []string) { setHistory(nextString(allArgs, &i, "history file path required")) case "--history-size": setHistoryMax(nextInt(allArgs, &i, "history max size required")) - case "--no-header-file": + case "--no-header": opts.Header = []string{} case "--no-header-lines": opts.HeaderLines = 0 - case "--header-file": - opts.Header = readHeaderFile( - nextString(allArgs, &i, "header file name required")) - opts.HeaderLines = 0 + case "--header": + opts.Header = strLines(nextString(allArgs, &i, "header string required")) case "--header-lines": - opts.Header = []string{} opts.HeaderLines = atoi( nextString(allArgs, &i, "number of header lines required")) case "--no-margin": @@ -843,11 +835,9 @@ func parseOptions(opts *Options, allArgs []string) { setHistory(value) } else if match, value := optString(arg, "--history-size="); match { setHistoryMax(atoi(value)) - } else if match, value := optString(arg, "--header-file="); match { - opts.Header = readHeaderFile(value) - opts.HeaderLines = 0 + } else if match, value := optString(arg, "--header="); match { + opts.Header = strLines(value) } else if match, value := optString(arg, "--header-lines="); match { - opts.Header = []string{} opts.HeaderLines = atoi(value) } else if match, value := optString(arg, "--margin="); match { opts.Margin = parseMargin(value) diff --git a/src/terminal.go b/src/terminal.go index c3fb966..5e8300f 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -42,6 +42,7 @@ type Terminal struct { history *History cycle bool header []string + header0 []string ansi bool margin [4]string marginInt [4]int @@ -185,6 +186,12 @@ func defaultKeymap() map[int]actionType { // NewTerminal returns new Terminal object func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal { input := []rune(opts.Query) + var header []string + if opts.Reverse { + header = opts.Header + } else { + header = reverseStringArray(opts.Header) + } return &Terminal{ inlineInfo: opts.InlineInfo, prompt: opts.Prompt, @@ -207,7 +214,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal { margin: opts.Margin, marginInt: [4]int{0, 0, 0, 0}, cycle: opts.Cycle, - header: opts.Header, + header: header, + header0: header, ansi: opts.Ansi, reading: true, merger: EmptyMerger, @@ -241,18 +249,19 @@ func (t *Terminal) UpdateCount(cnt int, final bool) { } } -// UpdateHeader updates the header -func (t *Terminal) UpdateHeader(header []string, lines int) { - t.mutex.Lock() - t.header = make([]string, lines) - copy(t.header, header) - if !t.reverse { - reversed := make([]string, lines) - for idx, str := range t.header { - reversed[lines-idx-1] = str - } - t.header = reversed +func reverseStringArray(input []string) []string { + size := len(input) + reversed := make([]string, size) + for idx, str := range input { + reversed[size-idx-1] = str } + return reversed +} + +// UpdateHeader updates the header +func (t *Terminal) UpdateHeader(header []string) { + t.mutex.Lock() + t.header = append(append([]string{}, t.header0...), header...) t.mutex.Unlock() t.reqBox.Set(reqHeader, nil) } @@ -436,9 +445,6 @@ func (t *Terminal) printHeader() { max := t.maxHeight() var state *ansiState for idx, lineStr := range t.header { - if !t.reverse { - idx = len(t.header) - idx - 1 - } line := idx + 2 if t.inlineInfo { line-- diff --git a/test/test_go.rb b/test/test_go.rb index 5b35264..e76b520 100644 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -737,8 +737,8 @@ class TestGoFZF < TestBase assert_equal '6', readonce.chomp end - def test_header_file - tmux.send_keys "seq 100 | #{fzf "--header-file <(head -5 #{__FILE__})"}", :Enter + def test_header + tmux.send_keys "seq 100 | #{fzf "--header \\\"\\$(head -5 #{__FILE__})\\\""}", :Enter header = File.readlines(__FILE__).take(5).map(&:strip) tmux.until do |lines| lines[-2].include?('100/100') && @@ -746,8 +746,8 @@ class TestGoFZF < TestBase end end - def test_header_file_reverse - tmux.send_keys "seq 100 | #{fzf "--header-file=<(head -5 #{__FILE__}) --reverse"}", :Enter + def test_header_reverse + tmux.send_keys "seq 100 | #{fzf "--header=\\\"\\$(head -5 #{__FILE__})\\\" --reverse"}", :Enter header = File.readlines(__FILE__).take(5).map(&:strip) tmux.until do |lines| lines[1].include?('100/100') && @@ -755,6 +755,26 @@ class TestGoFZF < TestBase end end + def test_header_and_header_lines + tmux.send_keys "seq 100 | #{fzf "--header-lines 10 --header \\\"\\$(head -5 #{__FILE__})\\\""}", :Enter + header = File.readlines(__FILE__).take(5).map(&:strip) + tmux.until do |lines| + lines[-2].include?('90/90') && + lines[-7...-2].map(&:strip) == header && + lines[-17...-7].map(&:strip) == (1..10).map(&:to_s).reverse + end + end + + def test_header_and_header_lines_reverse + tmux.send_keys "seq 100 | #{fzf "--reverse --header-lines 10 --header \\\"\\$(head -5 #{__FILE__})\\\""}", :Enter + header = File.readlines(__FILE__).take(5).map(&:strip) + tmux.until do |lines| + lines[1].include?('90/90') && + lines[2...7].map(&:strip) == header && + lines[7...17].map(&:strip) == (1..10).map(&:to_s) + end + end + def test_canel tmux.send_keys "seq 10 | #{fzf "--bind 2:cancel"}", :Enter tmux.until { |lines| lines[-2].include?('10/10') }