mirror of
https://github.com/junegunn/fzf.git
synced 2025-11-15 23:03:47 -05:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a71c471405 | ||
|
|
3858086047 | ||
|
|
dffef3d9f3 | ||
|
|
de1c6b8727 | ||
|
|
6f17f412ba | ||
|
|
746961bf43 | ||
|
|
182a6d99fd | ||
|
|
af31088481 | ||
|
|
43425158f4 | ||
|
|
8524ea7441 |
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,6 +1,21 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
0.15.9
|
||||
------
|
||||
- Fixed rendering glitches introduced in 0.15.8
|
||||
- The default escape delay is reduced to 50ms and is configurable via
|
||||
`$ESCDELAY`
|
||||
- Scroll indicator at the top-right corner of the preview window is always
|
||||
displayed when there's overflow
|
||||
- Can now be built with ncurses 6 or tcell to support extra features
|
||||
- *ncurses 6*
|
||||
- Supports more than 256 color pairs
|
||||
- Supports italics
|
||||
- *tcell*
|
||||
- 24-bit color support
|
||||
- See https://github.com/junegunn/fzf/blob/master/src/README.md#build
|
||||
|
||||
0.15.8
|
||||
------
|
||||
- Updated ANSI processor to handle more VT-100 escape sequences
|
||||
|
||||
4
install
4
install
@@ -2,8 +2,8 @@
|
||||
|
||||
set -u
|
||||
|
||||
[[ "$@" =~ --pre ]] && version=0.15.8 pre=1 ||
|
||||
version=0.15.8 pre=0
|
||||
[[ "$@" =~ --pre ]] && version=0.15.9 pre=1 ||
|
||||
version=0.15.9 pre=0
|
||||
|
||||
auto_completion=
|
||||
key_bindings=
|
||||
|
||||
@@ -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-tmux 1 "Nov 2016" "fzf 0.15.8" "fzf-tmux - open fzf in tmux split pane"
|
||||
.TH fzf-tmux 1 "Nov 2016" "fzf 0.15.9" "fzf-tmux - open fzf in tmux split pane"
|
||||
|
||||
.SH NAME
|
||||
fzf-tmux - open fzf in tmux split pane
|
||||
|
||||
@@ -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 "Nov 2016" "fzf 0.15.8" "fzf - a command-line fuzzy finder"
|
||||
.TH fzf 1 "Nov 2016" "fzf 0.15.9" "fzf - a command-line fuzzy finder"
|
||||
|
||||
.SH NAME
|
||||
fzf - a command-line fuzzy finder
|
||||
|
||||
@@ -70,10 +70,10 @@ clean:
|
||||
cd fzf && rm -f fzf-*
|
||||
|
||||
fzf/$(BINARY32): deps
|
||||
cd fzf && GOARCH=386 CGO_ENABLED=1 go build -a -ldflags -w -tags "$(TAGS)" -o $(BINARY32)
|
||||
cd fzf && GOARCH=386 CGO_ENABLED=1 go build -a -ldflags "-w -extldflags=$(LDFLAGS)" -tags "$(TAGS)" -o $(BINARY32)
|
||||
|
||||
fzf/$(BINARY64): deps
|
||||
cd fzf && go build -a -ldflags -w -tags "$(TAGS)" -o $(BINARY64)
|
||||
cd fzf && go build -a -ldflags "-w -extldflags=$(LDFLAGS)" -tags "$(TAGS)" -o $(BINARY64)
|
||||
|
||||
$(BINDIR)/fzf: fzf/$(BINARY) | $(BINDIR)
|
||||
cp -f fzf/$(BINARY) $(BINDIR)
|
||||
|
||||
@@ -61,6 +61,45 @@ make install
|
||||
make linux
|
||||
```
|
||||
|
||||
### With ncurses 6
|
||||
|
||||
The official binaries of fzf are built with ncurses 5 because it's widely
|
||||
supported by different platforms. However ncurses 5 is old and has a number of
|
||||
limitations.
|
||||
|
||||
1. Does not support more than 256 color pairs (See [357][357])
|
||||
2. Does not support italics
|
||||
3. Does not support 24-bit color
|
||||
|
||||
[357]: https://github.com/junegunn/fzf/issues/357
|
||||
|
||||
But you can manually build fzf with ncurses 6 to overcome some of these
|
||||
limitations. ncurses 6 supports up to 32767 color pairs (1), and supports
|
||||
italics (2). To build fzf with ncurses 6, you have to install it first. On
|
||||
macOS, you can use Homebrew to install it.
|
||||
|
||||
```sh
|
||||
brew install homebrew/dupes/ncurses
|
||||
LDFLAGS="-L/usr/local/opt/ncurses/lib" make install
|
||||
```
|
||||
|
||||
### With tcell
|
||||
|
||||
[tcell][tcell] is a portable alternative to ncurses and we currently use it to
|
||||
build Windows binaries. tcell has many benefits but most importantly, it
|
||||
supports 24-bit colors. To build fzf with tcell:
|
||||
|
||||
```sh
|
||||
TAGS=tcell make install
|
||||
```
|
||||
|
||||
However, note that tcell has its own issues.
|
||||
|
||||
- Poor rendering performance compared to ncurses
|
||||
- Does not support bracketed-paste mode
|
||||
- Does not support italics unlike ncurses 6
|
||||
- Some wide characters are not correctly displayed
|
||||
|
||||
Test
|
||||
----
|
||||
|
||||
@@ -88,6 +127,8 @@ Third-party libraries used
|
||||
- Licensed under [MIT](http://mattn.mit-license.org)
|
||||
- [mattn/go-isatty](https://github.com/mattn/go-isatty)
|
||||
- Licensed under [MIT](http://mattn.mit-license.org)
|
||||
- [tcell](https://github.com/gdamore/tcell)
|
||||
- Licensed under [Apache License 2.0](https://github.com/gdamore/tcell/blob/master/LICENSE)
|
||||
|
||||
License
|
||||
-------
|
||||
@@ -99,4 +140,4 @@ License
|
||||
[gil]: http://en.wikipedia.org/wiki/Global_Interpreter_Lock
|
||||
[ncurses]: https://www.gnu.org/software/ncurses/
|
||||
[req]: http://golang.org/doc/install
|
||||
[termbox]: https://github.com/nsf/termbox-go
|
||||
[tcell]: https://github.com/gdamore/tcell
|
||||
|
||||
26
src/ansi.go
26
src/ansi.go
@@ -143,15 +143,17 @@ func interpretCode(ansiCode string, prevState *ansiState) *ansiState {
|
||||
case 49:
|
||||
state.bg = -1
|
||||
case 1:
|
||||
state.attr = tui.Bold
|
||||
state.attr = state.attr | tui.Bold
|
||||
case 2:
|
||||
state.attr = tui.Dim
|
||||
state.attr = state.attr | tui.Dim
|
||||
case 3:
|
||||
state.attr = state.attr | tui.Italic
|
||||
case 4:
|
||||
state.attr = tui.Underline
|
||||
state.attr = state.attr | tui.Underline
|
||||
case 5:
|
||||
state.attr = tui.Blink
|
||||
state.attr = state.attr | tui.Blink
|
||||
case 7:
|
||||
state.attr = tui.Reverse
|
||||
state.attr = state.attr | tui.Reverse
|
||||
case 0:
|
||||
init()
|
||||
default:
|
||||
@@ -167,6 +169,8 @@ func interpretCode(ansiCode string, prevState *ansiState) *ansiState {
|
||||
}
|
||||
case 1:
|
||||
switch num {
|
||||
case 2:
|
||||
state256 = 10 // MAGIC
|
||||
case 5:
|
||||
state256++
|
||||
default:
|
||||
@@ -175,8 +179,20 @@ func interpretCode(ansiCode string, prevState *ansiState) *ansiState {
|
||||
case 2:
|
||||
*ptr = tui.Color(num)
|
||||
state256 = 0
|
||||
case 10:
|
||||
*ptr = tui.Color(1<<24) | tui.Color(num<<16)
|
||||
state256++
|
||||
case 11:
|
||||
*ptr = *ptr | tui.Color(num<<8)
|
||||
state256++
|
||||
case 12:
|
||||
*ptr = *ptr | tui.Color(num)
|
||||
state256 = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
if state256 > 0 {
|
||||
*ptr = -1
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
const (
|
||||
// Current version
|
||||
version = "0.15.8"
|
||||
version = "0.15.9"
|
||||
|
||||
// Core
|
||||
coordinatorDelayMax time.Duration = 100 * time.Millisecond
|
||||
|
||||
@@ -190,6 +190,7 @@ const (
|
||||
func defaultKeymap() map[int]actionType {
|
||||
keymap := make(map[int]actionType)
|
||||
keymap[tui.Invalid] = actInvalid
|
||||
keymap[tui.Resize] = actClearScreen
|
||||
keymap[tui.CtrlA] = actBeginningOfLine
|
||||
keymap[tui.CtrlB] = actBackwardChar
|
||||
keymap[tui.CtrlC] = actAbort
|
||||
@@ -832,7 +833,7 @@ func (t *Terminal) printPreview() {
|
||||
}
|
||||
return t.pwindow.Fill(str)
|
||||
})
|
||||
if t.previewer.offset > 0 {
|
||||
if t.previewer.lines > t.pwindow.Height {
|
||||
offset := fmt.Sprintf("%d/%d", t.previewer.offset+1, t.previewer.lines)
|
||||
t.pwindow.Move(0, t.pwindow.Width-len(offset))
|
||||
t.pwindow.CPrint(tui.ColInfo, tui.Reverse, offset)
|
||||
|
||||
@@ -23,13 +23,14 @@ import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type ColorPair int16
|
||||
type Attr C.int
|
||||
type Attr C.uint
|
||||
type WindowImpl C.WINDOW
|
||||
|
||||
const (
|
||||
@@ -40,6 +41,8 @@ const (
|
||||
Underline = C.A_UNDERLINE
|
||||
)
|
||||
|
||||
var Italic Attr = C.A_VERTICAL << 1 // FIXME
|
||||
|
||||
const (
|
||||
AttrRegular Attr = 0
|
||||
)
|
||||
@@ -64,11 +67,14 @@ const (
|
||||
var (
|
||||
_screen *C.SCREEN
|
||||
_colorMap map[int]ColorPair
|
||||
_colorFn func(ColorPair, Attr) C.int
|
||||
_colorFn func(ColorPair, Attr) (C.short, C.int)
|
||||
)
|
||||
|
||||
func init() {
|
||||
_colorMap = make(map[int]ColorPair)
|
||||
if strings.HasPrefix(C.GoString(C.curses_version()), "ncurses 5") {
|
||||
Italic = C.A_NORMAL
|
||||
}
|
||||
}
|
||||
|
||||
func (a Attr) Merge(b Attr) Attr {
|
||||
@@ -103,8 +109,16 @@ func Init(theme *ColorTheme, black bool, mouse bool) {
|
||||
C.raw() // stty dsusp undef
|
||||
C.nonl()
|
||||
C.keypad(C.stdscr, true)
|
||||
C.set_escdelay(100)
|
||||
C.timeout(100) // ESCDELAY 100ms + timeout 100ms
|
||||
|
||||
delay := 50
|
||||
delayEnv := os.Getenv("ESCDELAY")
|
||||
if len(delayEnv) > 0 {
|
||||
num, err := strconv.Atoi(delayEnv)
|
||||
if err == nil && num >= 0 {
|
||||
delay = num
|
||||
}
|
||||
}
|
||||
C.set_escdelay(C.int(delay))
|
||||
|
||||
_color = theme != nil
|
||||
if _color {
|
||||
@@ -116,6 +130,13 @@ func Init(theme *ColorTheme, black bool, mouse bool) {
|
||||
} else {
|
||||
_colorFn = attrMono
|
||||
}
|
||||
|
||||
C.nodelay(C.stdscr, true)
|
||||
ch := C.getch()
|
||||
if ch != C.ERR {
|
||||
C.ungetch(ch)
|
||||
}
|
||||
C.nodelay(C.stdscr, false)
|
||||
}
|
||||
|
||||
func initPairs(theme *ColorTheme) {
|
||||
@@ -155,10 +176,12 @@ func NewWindow(top int, left int, width int, height int, border bool) *Window {
|
||||
C.wbkgd(win, C.chtype(C.COLOR_PAIR(C.int(ColNormal))))
|
||||
}
|
||||
if border {
|
||||
attr := _colorFn(ColBorder, 0)
|
||||
pair, attr := _colorFn(ColBorder, 0)
|
||||
C.wcolor_set(win, pair, nil)
|
||||
C.wattron(win, attr)
|
||||
C.box(win, 0, 0)
|
||||
C.wattroff(win, attr)
|
||||
C.wcolor_set(win, 0, nil)
|
||||
}
|
||||
|
||||
return &Window{
|
||||
@@ -170,15 +193,11 @@ func NewWindow(top int, left int, width int, height int, border bool) *Window {
|
||||
}
|
||||
}
|
||||
|
||||
func attrColored(pair ColorPair, a Attr) C.int {
|
||||
var attr C.int
|
||||
if pair > 0 {
|
||||
attr = C.COLOR_PAIR(C.int(pair))
|
||||
}
|
||||
return attr | C.int(a)
|
||||
func attrColored(pair ColorPair, a Attr) (C.short, C.int) {
|
||||
return C.short(pair), C.int(a)
|
||||
}
|
||||
|
||||
func attrMono(pair ColorPair, a Attr) C.int {
|
||||
func attrMono(pair ColorPair, a Attr) (C.short, C.int) {
|
||||
var attr C.int
|
||||
switch pair {
|
||||
case ColCurrent:
|
||||
@@ -191,7 +210,7 @@ func attrMono(pair ColorPair, a Attr) C.int {
|
||||
if C.int(a)&C.A_BOLD == C.A_BOLD {
|
||||
attr = attr | C.A_BOLD
|
||||
}
|
||||
return attr
|
||||
return 0, attr
|
||||
}
|
||||
|
||||
func MaxX() int {
|
||||
@@ -232,11 +251,13 @@ func (w *Window) Print(text string) {
|
||||
}, text)))
|
||||
}
|
||||
|
||||
func (w *Window) CPrint(pair ColorPair, a Attr, text string) {
|
||||
attr := _colorFn(pair, a)
|
||||
C.wattron(w.win(), attr)
|
||||
func (w *Window) CPrint(pair ColorPair, attr Attr, text string) {
|
||||
p, a := _colorFn(pair, attr)
|
||||
C.wcolor_set(w.win(), p, nil)
|
||||
C.wattron(w.win(), a)
|
||||
w.Print(text)
|
||||
C.wattroff(w.win(), attr)
|
||||
C.wattroff(w.win(), a)
|
||||
C.wcolor_set(w.win(), 0, nil)
|
||||
}
|
||||
|
||||
func Clear() {
|
||||
@@ -256,11 +277,13 @@ func (w *Window) Fill(str string) bool {
|
||||
return C.waddstr(w.win(), C.CString(str)) == C.OK
|
||||
}
|
||||
|
||||
func (w *Window) CFill(str string, fg Color, bg Color, a Attr) bool {
|
||||
attr := _colorFn(PairFor(fg, bg), a)
|
||||
C.wattron(w.win(), attr)
|
||||
func (w *Window) CFill(str string, fg Color, bg Color, attr Attr) bool {
|
||||
pair := PairFor(fg, bg)
|
||||
C.wcolor_set(w.win(), C.short(pair), nil)
|
||||
C.wattron(w.win(), C.int(attr))
|
||||
ret := w.Fill(str)
|
||||
C.wattroff(w.win(), attr)
|
||||
C.wattroff(w.win(), C.int(attr))
|
||||
C.wcolor_set(w.win(), 0, nil)
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -272,6 +295,10 @@ func RefreshWindows(windows []*Window) {
|
||||
}
|
||||
|
||||
func PairFor(fg Color, bg Color) ColorPair {
|
||||
// ncurses does not support 24-bit colors
|
||||
if fg.is24() || bg.is24() {
|
||||
return ColDefault
|
||||
}
|
||||
key := (int(fg) << 8) + int(bg)
|
||||
if found, prs := _colorMap[key]; prs {
|
||||
return found
|
||||
@@ -293,8 +320,10 @@ func consume(expects ...rune) bool {
|
||||
}
|
||||
|
||||
func escSequence() Event {
|
||||
// nodelay is not thread-safe (e.g. <ESC><CTRL-P>)
|
||||
// C.nodelay(C.stdscr, true)
|
||||
C.nodelay(C.stdscr, true)
|
||||
defer func() {
|
||||
C.nodelay(C.stdscr, false)
|
||||
}()
|
||||
c := C.getch()
|
||||
switch c {
|
||||
case C.ERR:
|
||||
@@ -416,7 +445,7 @@ func GetChar() Event {
|
||||
}
|
||||
return Event{Invalid, 0, nil}
|
||||
case C.KEY_RESIZE:
|
||||
return Event{Invalid, 0, nil}
|
||||
return Event{Resize, 0, nil}
|
||||
case ESC:
|
||||
return escSequence()
|
||||
case 127:
|
||||
|
||||
@@ -11,8 +11,9 @@ import (
|
||||
|
||||
"runtime"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/gdamore/tcell/encoding"
|
||||
// https://github.com/gdamore/tcell/pull/135
|
||||
"github.com/junegunn/tcell"
|
||||
"github.com/junegunn/tcell/encoding"
|
||||
|
||||
"github.com/junegunn/go-runewidth"
|
||||
)
|
||||
@@ -48,6 +49,7 @@ const (
|
||||
Blink = Attr(tcell.AttrBlink)
|
||||
Reverse = Attr(tcell.AttrReverse)
|
||||
Underline = Attr(tcell.AttrUnderline)
|
||||
Italic = Attr(tcell.AttrNone) // Not supported
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -183,7 +185,7 @@ func GetChar() Event {
|
||||
ev := _screen.PollEvent()
|
||||
switch ev := ev.(type) {
|
||||
case *tcell.EventResize:
|
||||
return Event{Invalid, 0, nil}
|
||||
return Event{Resize, 0, nil}
|
||||
|
||||
// process mouse events:
|
||||
case *tcell.EventMouse:
|
||||
|
||||
@@ -37,6 +37,7 @@ const (
|
||||
ESC
|
||||
|
||||
Invalid
|
||||
Resize
|
||||
Mouse
|
||||
DoubleClick
|
||||
|
||||
@@ -92,7 +93,11 @@ const (
|
||||
doubleClickDuration = 500 * time.Millisecond
|
||||
)
|
||||
|
||||
type Color int16
|
||||
type Color int32
|
||||
|
||||
func (c Color) is24() bool {
|
||||
return c > 0 && (c&(1<<24)) > 0
|
||||
}
|
||||
|
||||
const (
|
||||
colUndefined Color = -2
|
||||
|
||||
Reference in New Issue
Block a user