Replace --header-file with --header (#346)
and allow using --header and --header-lines at the same time. Close #346.
This commit is contained in:
parent
65d9d416b4
commit
2022a3ad96
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,6 +1,16 @@
|
|||||||
CHANGELOG
|
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
|
0.10.5
|
||||||
------
|
------
|
||||||
|
|
||||||
|
@ -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
|
Maximum number of entries in the history file (default: 1000). The file is
|
||||||
automatically truncated when the number of the lines exceeds the value.
|
automatically truncated when the number of the lines exceeds the value.
|
||||||
.TP
|
.TP
|
||||||
.BI "--header-file=" "FILE"
|
.BI "--header=" "STR"
|
||||||
The content of the file will be printed as the sticky header. The lines in the
|
The given string will be printed as the sticky header. The lines are displayed
|
||||||
file are displayed in order from top to bottom regardless of \fB--reverse\fR,
|
in the given order from top to bottom regardless of \fB--reverse\fR option, and
|
||||||
and are not affected by \fB--with-nth\fR. ANSI color codes are processed even
|
are not affected by \fB--with-nth\fR. ANSI color codes are processed even when
|
||||||
when \fB--ansi\fR is not set.
|
\fB--ansi\fR is not set.
|
||||||
.TP
|
.TP
|
||||||
.BI "--header-lines=" "N"
|
.BI "--header-lines=" "N"
|
||||||
The first N lines of the input are treated as the sticky header. When
|
The first N lines of the input are treated as the sticky header. When
|
||||||
|
@ -49,7 +49,7 @@ _fzf_opts_completion() {
|
|||||||
--cycle
|
--cycle
|
||||||
--history
|
--history
|
||||||
--history-size
|
--history-size
|
||||||
--header-file
|
--header
|
||||||
--header-lines
|
--header-lines
|
||||||
--margin"
|
--margin"
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ _fzf_opts_completion() {
|
|||||||
COMPREPLY=( $(compgen -W "dark light 16 bw" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "dark light 16 bw" -- ${cur}) )
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
--history|--header-file)
|
--history)
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
@ -238,7 +238,7 @@ func Run(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case EvtHeader:
|
case EvtHeader:
|
||||||
terminal.UpdateHeader(value.([]string), opts.HeaderLines)
|
terminal.UpdateHeader(value.([]string))
|
||||||
|
|
||||||
case EvtSearchFin:
|
case EvtSearchFin:
|
||||||
switch val := value.(type) {
|
switch val := value.(type) {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package fzf
|
package fzf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -45,7 +44,7 @@ const usage = `usage: fzf [options]
|
|||||||
--bind=KEYBINDS Custom key bindings. Refer to the man page.
|
--bind=KEYBINDS Custom key bindings. Refer to the man page.
|
||||||
--history=FILE History file
|
--history=FILE History file
|
||||||
--history-size=N Maximum number of history entries (default: 1000)
|
--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
|
--header-lines=N The first N lines of the input are treated as header
|
||||||
|
|
||||||
Scripting
|
Scripting
|
||||||
@ -604,12 +603,8 @@ func checkToggleSort(keymap map[int]actionType, str string) map[int]actionType {
|
|||||||
return keymap
|
return keymap
|
||||||
}
|
}
|
||||||
|
|
||||||
func readHeaderFile(filename string) []string {
|
func strLines(str string) []string {
|
||||||
content, err := ioutil.ReadFile(filename)
|
return strings.Split(strings.TrimSuffix(str, "\n"), "\n")
|
||||||
if err != nil {
|
|
||||||
errorExit("failed to read header file: " + filename)
|
|
||||||
}
|
|
||||||
return strings.Split(strings.TrimSuffix(string(content), "\n"), "\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseMargin(margin string) [4]string {
|
func parseMargin(margin string) [4]string {
|
||||||
@ -793,16 +788,13 @@ func parseOptions(opts *Options, allArgs []string) {
|
|||||||
setHistory(nextString(allArgs, &i, "history file path required"))
|
setHistory(nextString(allArgs, &i, "history file path required"))
|
||||||
case "--history-size":
|
case "--history-size":
|
||||||
setHistoryMax(nextInt(allArgs, &i, "history max size required"))
|
setHistoryMax(nextInt(allArgs, &i, "history max size required"))
|
||||||
case "--no-header-file":
|
case "--no-header":
|
||||||
opts.Header = []string{}
|
opts.Header = []string{}
|
||||||
case "--no-header-lines":
|
case "--no-header-lines":
|
||||||
opts.HeaderLines = 0
|
opts.HeaderLines = 0
|
||||||
case "--header-file":
|
case "--header":
|
||||||
opts.Header = readHeaderFile(
|
opts.Header = strLines(nextString(allArgs, &i, "header string required"))
|
||||||
nextString(allArgs, &i, "header file name required"))
|
|
||||||
opts.HeaderLines = 0
|
|
||||||
case "--header-lines":
|
case "--header-lines":
|
||||||
opts.Header = []string{}
|
|
||||||
opts.HeaderLines = atoi(
|
opts.HeaderLines = atoi(
|
||||||
nextString(allArgs, &i, "number of header lines required"))
|
nextString(allArgs, &i, "number of header lines required"))
|
||||||
case "--no-margin":
|
case "--no-margin":
|
||||||
@ -843,11 +835,9 @@ func parseOptions(opts *Options, allArgs []string) {
|
|||||||
setHistory(value)
|
setHistory(value)
|
||||||
} else if match, value := optString(arg, "--history-size="); match {
|
} else if match, value := optString(arg, "--history-size="); match {
|
||||||
setHistoryMax(atoi(value))
|
setHistoryMax(atoi(value))
|
||||||
} else if match, value := optString(arg, "--header-file="); match {
|
} else if match, value := optString(arg, "--header="); match {
|
||||||
opts.Header = readHeaderFile(value)
|
opts.Header = strLines(value)
|
||||||
opts.HeaderLines = 0
|
|
||||||
} else if match, value := optString(arg, "--header-lines="); match {
|
} else if match, value := optString(arg, "--header-lines="); match {
|
||||||
opts.Header = []string{}
|
|
||||||
opts.HeaderLines = atoi(value)
|
opts.HeaderLines = atoi(value)
|
||||||
} else if match, value := optString(arg, "--margin="); match {
|
} else if match, value := optString(arg, "--margin="); match {
|
||||||
opts.Margin = parseMargin(value)
|
opts.Margin = parseMargin(value)
|
||||||
|
@ -42,6 +42,7 @@ type Terminal struct {
|
|||||||
history *History
|
history *History
|
||||||
cycle bool
|
cycle bool
|
||||||
header []string
|
header []string
|
||||||
|
header0 []string
|
||||||
ansi bool
|
ansi bool
|
||||||
margin [4]string
|
margin [4]string
|
||||||
marginInt [4]int
|
marginInt [4]int
|
||||||
@ -185,6 +186,12 @@ func defaultKeymap() map[int]actionType {
|
|||||||
// NewTerminal returns new Terminal object
|
// NewTerminal returns new Terminal object
|
||||||
func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
||||||
input := []rune(opts.Query)
|
input := []rune(opts.Query)
|
||||||
|
var header []string
|
||||||
|
if opts.Reverse {
|
||||||
|
header = opts.Header
|
||||||
|
} else {
|
||||||
|
header = reverseStringArray(opts.Header)
|
||||||
|
}
|
||||||
return &Terminal{
|
return &Terminal{
|
||||||
inlineInfo: opts.InlineInfo,
|
inlineInfo: opts.InlineInfo,
|
||||||
prompt: opts.Prompt,
|
prompt: opts.Prompt,
|
||||||
@ -207,7 +214,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
|||||||
margin: opts.Margin,
|
margin: opts.Margin,
|
||||||
marginInt: [4]int{0, 0, 0, 0},
|
marginInt: [4]int{0, 0, 0, 0},
|
||||||
cycle: opts.Cycle,
|
cycle: opts.Cycle,
|
||||||
header: opts.Header,
|
header: header,
|
||||||
|
header0: header,
|
||||||
ansi: opts.Ansi,
|
ansi: opts.Ansi,
|
||||||
reading: true,
|
reading: true,
|
||||||
merger: EmptyMerger,
|
merger: EmptyMerger,
|
||||||
@ -241,18 +249,19 @@ func (t *Terminal) UpdateCount(cnt int, final bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateHeader updates the header
|
func reverseStringArray(input []string) []string {
|
||||||
func (t *Terminal) UpdateHeader(header []string, lines int) {
|
size := len(input)
|
||||||
t.mutex.Lock()
|
reversed := make([]string, size)
|
||||||
t.header = make([]string, lines)
|
for idx, str := range input {
|
||||||
copy(t.header, header)
|
reversed[size-idx-1] = str
|
||||||
if !t.reverse {
|
|
||||||
reversed := make([]string, lines)
|
|
||||||
for idx, str := range t.header {
|
|
||||||
reversed[lines-idx-1] = str
|
|
||||||
}
|
|
||||||
t.header = reversed
|
|
||||||
}
|
}
|
||||||
|
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.mutex.Unlock()
|
||||||
t.reqBox.Set(reqHeader, nil)
|
t.reqBox.Set(reqHeader, nil)
|
||||||
}
|
}
|
||||||
@ -436,9 +445,6 @@ func (t *Terminal) printHeader() {
|
|||||||
max := t.maxHeight()
|
max := t.maxHeight()
|
||||||
var state *ansiState
|
var state *ansiState
|
||||||
for idx, lineStr := range t.header {
|
for idx, lineStr := range t.header {
|
||||||
if !t.reverse {
|
|
||||||
idx = len(t.header) - idx - 1
|
|
||||||
}
|
|
||||||
line := idx + 2
|
line := idx + 2
|
||||||
if t.inlineInfo {
|
if t.inlineInfo {
|
||||||
line--
|
line--
|
||||||
|
@ -737,8 +737,8 @@ class TestGoFZF < TestBase
|
|||||||
assert_equal '6', readonce.chomp
|
assert_equal '6', readonce.chomp
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_header_file
|
def test_header
|
||||||
tmux.send_keys "seq 100 | #{fzf "--header-file <(head -5 #{__FILE__})"}", :Enter
|
tmux.send_keys "seq 100 | #{fzf "--header \\\"\\$(head -5 #{__FILE__})\\\""}", :Enter
|
||||||
header = File.readlines(__FILE__).take(5).map(&:strip)
|
header = File.readlines(__FILE__).take(5).map(&:strip)
|
||||||
tmux.until do |lines|
|
tmux.until do |lines|
|
||||||
lines[-2].include?('100/100') &&
|
lines[-2].include?('100/100') &&
|
||||||
@ -746,8 +746,8 @@ class TestGoFZF < TestBase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_header_file_reverse
|
def test_header_reverse
|
||||||
tmux.send_keys "seq 100 | #{fzf "--header-file=<(head -5 #{__FILE__}) --reverse"}", :Enter
|
tmux.send_keys "seq 100 | #{fzf "--header=\\\"\\$(head -5 #{__FILE__})\\\" --reverse"}", :Enter
|
||||||
header = File.readlines(__FILE__).take(5).map(&:strip)
|
header = File.readlines(__FILE__).take(5).map(&:strip)
|
||||||
tmux.until do |lines|
|
tmux.until do |lines|
|
||||||
lines[1].include?('100/100') &&
|
lines[1].include?('100/100') &&
|
||||||
@ -755,6 +755,26 @@ class TestGoFZF < TestBase
|
|||||||
end
|
end
|
||||||
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
|
def test_canel
|
||||||
tmux.send_keys "seq 10 | #{fzf "--bind 2:cancel"}", :Enter
|
tmux.send_keys "seq 10 | #{fzf "--bind 2:cancel"}", :Enter
|
||||||
tmux.until { |lines| lines[-2].include?('10/10') }
|
tmux.until { |lines| lines[-2].include?('10/10') }
|
||||||
|
Loading…
Reference in New Issue
Block a user