mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-11-10 15:50:56 +00:00
Add --header-file option
This commit is contained in:
parent
c9abe1b1ff
commit
d459e9abce
@ -122,6 +122,7 @@ e.g. \fBfzf --color=bg+:24\fR
|
|||||||
\fBpointer \fRPointer to the current line
|
\fBpointer \fRPointer to the current line
|
||||||
\fBmarker \fRMulti-select marker
|
\fBmarker \fRMulti-select marker
|
||||||
\fBspinner \fRStreaming input indicator
|
\fBspinner \fRStreaming input indicator
|
||||||
|
\fBheader \fRHeader
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
.B "--black"
|
.B "--black"
|
||||||
|
@ -94,6 +94,7 @@ const (
|
|||||||
ColInfo
|
ColInfo
|
||||||
ColCursor
|
ColCursor
|
||||||
ColSelected
|
ColSelected
|
||||||
|
ColHeader
|
||||||
ColUser
|
ColUser
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -114,6 +115,7 @@ type ColorTheme struct {
|
|||||||
Info int16
|
Info int16
|
||||||
Cursor int16
|
Cursor int16
|
||||||
Selected int16
|
Selected int16
|
||||||
|
Header int16
|
||||||
}
|
}
|
||||||
|
|
||||||
type Event struct {
|
type Event struct {
|
||||||
@ -164,7 +166,8 @@ func init() {
|
|||||||
Spinner: C.COLOR_GREEN,
|
Spinner: C.COLOR_GREEN,
|
||||||
Info: C.COLOR_WHITE,
|
Info: C.COLOR_WHITE,
|
||||||
Cursor: C.COLOR_RED,
|
Cursor: C.COLOR_RED,
|
||||||
Selected: C.COLOR_MAGENTA}
|
Selected: C.COLOR_MAGENTA,
|
||||||
|
Header: C.COLOR_CYAN}
|
||||||
Dark256 = &ColorTheme{
|
Dark256 = &ColorTheme{
|
||||||
UseDefault: true,
|
UseDefault: true,
|
||||||
Fg: 15,
|
Fg: 15,
|
||||||
@ -177,7 +180,8 @@ func init() {
|
|||||||
Spinner: 148,
|
Spinner: 148,
|
||||||
Info: 144,
|
Info: 144,
|
||||||
Cursor: 161,
|
Cursor: 161,
|
||||||
Selected: 168}
|
Selected: 168,
|
||||||
|
Header: 110}
|
||||||
Light256 = &ColorTheme{
|
Light256 = &ColorTheme{
|
||||||
UseDefault: true,
|
UseDefault: true,
|
||||||
Fg: 15,
|
Fg: 15,
|
||||||
@ -190,7 +194,8 @@ func init() {
|
|||||||
Spinner: 65,
|
Spinner: 65,
|
||||||
Info: 101,
|
Info: 101,
|
||||||
Cursor: 161,
|
Cursor: 161,
|
||||||
Selected: 168}
|
Selected: 168,
|
||||||
|
Header: 31}
|
||||||
}
|
}
|
||||||
|
|
||||||
func attrColored(pair int, bold bool) C.int {
|
func attrColored(pair int, bold bool) C.int {
|
||||||
@ -308,6 +313,7 @@ func initPairs(theme *ColorTheme, black bool) {
|
|||||||
C.init_pair(ColInfo, C.short(theme.Info), bg)
|
C.init_pair(ColInfo, C.short(theme.Info), bg)
|
||||||
C.init_pair(ColCursor, C.short(theme.Cursor), darkBG)
|
C.init_pair(ColCursor, C.short(theme.Cursor), darkBG)
|
||||||
C.init_pair(ColSelected, C.short(theme.Selected), darkBG)
|
C.init_pair(ColSelected, C.short(theme.Selected), darkBG)
|
||||||
|
C.init_pair(ColHeader, C.short(theme.Header), bg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Close() {
|
func Close() {
|
||||||
|
@ -2,6 +2,7 @@ package fzf
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -44,6 +45,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=N Header file
|
||||||
|
|
||||||
Scripting
|
Scripting
|
||||||
-q, --query=STR Start the finder with the given query
|
-q, --query=STR Start the finder with the given query
|
||||||
@ -122,6 +124,7 @@ type Options struct {
|
|||||||
ReadZero bool
|
ReadZero bool
|
||||||
Sync bool
|
Sync bool
|
||||||
History *History
|
History *History
|
||||||
|
Header []string
|
||||||
Version bool
|
Version bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +167,7 @@ func defaultOptions() *Options {
|
|||||||
ReadZero: false,
|
ReadZero: false,
|
||||||
Sync: false,
|
Sync: false,
|
||||||
History: nil,
|
History: nil,
|
||||||
|
Header: make([]string, 0),
|
||||||
Version: false}
|
Version: false}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,6 +417,8 @@ func parseTheme(defaultTheme *curses.ColorTheme, str string) *curses.ColorTheme
|
|||||||
theme.Cursor = ansi
|
theme.Cursor = ansi
|
||||||
case "marker":
|
case "marker":
|
||||||
theme.Selected = ansi
|
theme.Selected = ansi
|
||||||
|
case "header":
|
||||||
|
theme.Header = ansi
|
||||||
default:
|
default:
|
||||||
fail()
|
fail()
|
||||||
}
|
}
|
||||||
@ -571,6 +577,14 @@ func checkToggleSort(keymap map[int]actionType, str string) map[int]actionType {
|
|||||||
return keymap
|
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 parseOptions(opts *Options, allArgs []string) {
|
func parseOptions(opts *Options, allArgs []string) {
|
||||||
keymap := make(map[int]actionType)
|
keymap := make(map[int]actionType)
|
||||||
var historyMax int
|
var historyMax int
|
||||||
@ -710,6 +724,9 @@ 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 "--header-file":
|
||||||
|
opts.Header = readHeaderFile(
|
||||||
|
nextString(allArgs, &i, "header file name required"))
|
||||||
case "--version":
|
case "--version":
|
||||||
opts.Version = true
|
opts.Version = true
|
||||||
default:
|
default:
|
||||||
@ -743,6 +760,8 @@ 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 {
|
||||||
|
opts.Header = readHeaderFile(value)
|
||||||
} else {
|
} else {
|
||||||
errorExit("unknown option: " + arg)
|
errorExit("unknown option: " + arg)
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ type Terminal struct {
|
|||||||
printQuery bool
|
printQuery bool
|
||||||
history *History
|
history *History
|
||||||
cycle bool
|
cycle bool
|
||||||
|
header []string
|
||||||
count int
|
count int
|
||||||
progress int
|
progress int
|
||||||
reading bool
|
reading bool
|
||||||
@ -197,6 +198,7 @@ func NewTerminal(opts *Options, eventBox *util.EventBox) *Terminal {
|
|||||||
printQuery: opts.PrintQuery,
|
printQuery: opts.PrintQuery,
|
||||||
history: opts.History,
|
history: opts.History,
|
||||||
cycle: opts.Cycle,
|
cycle: opts.Cycle,
|
||||||
|
header: opts.Header,
|
||||||
reading: true,
|
reading: true,
|
||||||
merger: EmptyMerger,
|
merger: EmptyMerger,
|
||||||
selected: make(map[uint32]selectedItem),
|
selected: make(map[uint32]selectedItem),
|
||||||
@ -354,17 +356,39 @@ func (t *Terminal) printInfo() {
|
|||||||
C.CPrint(C.ColInfo, false, output)
|
C.CPrint(C.ColInfo, false, output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Terminal) printHeader() {
|
||||||
|
if len(t.header) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for idx, lineStr := range t.header {
|
||||||
|
if !t.reverse {
|
||||||
|
idx = len(t.header) - idx - 1
|
||||||
|
}
|
||||||
|
trimmed, colors := extractColor(&lineStr)
|
||||||
|
item := &Item{
|
||||||
|
text: trimmed,
|
||||||
|
index: 0,
|
||||||
|
colors: colors,
|
||||||
|
rank: Rank{0, 0, 0}}
|
||||||
|
|
||||||
|
line := idx + 2
|
||||||
|
if t.inlineInfo {
|
||||||
|
line -= 1
|
||||||
|
}
|
||||||
|
t.move(line, 2, true)
|
||||||
|
t.printHighlighted(item, false, C.ColHeader, 0, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Terminal) printList() {
|
func (t *Terminal) printList() {
|
||||||
t.constrain()
|
t.constrain()
|
||||||
|
|
||||||
maxy := t.maxItems()
|
maxy := t.maxItems()
|
||||||
count := t.merger.Length() - t.offset
|
count := t.merger.Length() - t.offset
|
||||||
for i := 0; i < maxy; i++ {
|
for i := 0; i < maxy; i++ {
|
||||||
var line int
|
line := i + 2 + len(t.header)
|
||||||
if t.inlineInfo {
|
if t.inlineInfo {
|
||||||
line = i + 1
|
line -= 1
|
||||||
} else {
|
|
||||||
line = i + 2
|
|
||||||
}
|
}
|
||||||
t.move(line, 0, true)
|
t.move(line, 0, true)
|
||||||
if i < count {
|
if i < count {
|
||||||
@ -606,6 +630,7 @@ func (t *Terminal) Loop() {
|
|||||||
t.placeCursor()
|
t.placeCursor()
|
||||||
C.Refresh()
|
C.Refresh()
|
||||||
t.printInfo()
|
t.printInfo()
|
||||||
|
t.printHeader()
|
||||||
t.mutex.Unlock()
|
t.mutex.Unlock()
|
||||||
go func() {
|
go func() {
|
||||||
timer := time.NewTimer(initialDelay)
|
timer := time.NewTimer(initialDelay)
|
||||||
@ -883,9 +908,9 @@ func (t *Terminal) Loop() {
|
|||||||
if !t.reverse {
|
if !t.reverse {
|
||||||
my = C.MaxY() - my - 1
|
my = C.MaxY() - my - 1
|
||||||
}
|
}
|
||||||
min := 2
|
min := 2 + len(t.header)
|
||||||
if t.inlineInfo {
|
if t.inlineInfo {
|
||||||
min = 1
|
min -= 1
|
||||||
}
|
}
|
||||||
if me.S != 0 {
|
if me.S != 0 {
|
||||||
// Scroll
|
// Scroll
|
||||||
@ -977,7 +1002,7 @@ func (t *Terminal) vset(o int) bool {
|
|||||||
|
|
||||||
func (t *Terminal) maxItems() int {
|
func (t *Terminal) maxItems() int {
|
||||||
if t.inlineInfo {
|
if t.inlineInfo {
|
||||||
return C.MaxY() - 1
|
return C.MaxY() - 1 - len(t.header)
|
||||||
}
|
}
|
||||||
return C.MaxY() - 2
|
return C.MaxY() - 2 - len(t.header)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user