m/fzf
1
0
mirror of https://github.com/junegunn/fzf.git synced 2025-11-16 07:13:48 -05:00

Compare commits

...

10 Commits

Author SHA1 Message Date
Junegunn Choi
a71c471405 0.15.9 2016-11-26 12:36:24 +09:00
Junegunn Choi
3858086047 Always print scroll indicator in preview window 2016-11-26 12:34:16 +09:00
Junegunn Choi
dffef3d9f3 Update build instructions for ncurses 6 and tcell
Close #357
Close #738
2016-11-26 11:41:57 +09:00
Junegunn Choi
de1c6b8727 [tcell] 24-bit color support
TAGS=tcell make install

    printf "\x1b[38;2;100;200;250mTRUECOLOR\x1b[m\n" |
        TERM=xterm-truecolor fzf --ansi
2016-11-26 00:36:38 +09:00
Junegunn Choi
6f17f412ba Workaround for rendering glitch in case of short-lived input process
: | fzf --preview 'echo foo'
2016-11-25 14:05:37 +09:00
Junegunn Choi
746961bf43 [ncurses6] Suppress tui.Italic on ncurses 5 2016-11-24 13:42:14 +09:00
Junegunn Choi
182a6d99fd [ncurses6] Support italics 2016-11-24 00:13:10 +09:00
Junegunn Choi
af31088481 [ncurses6] Use wcolor_set to support more than 256 color pairs
To build fzf with ncurses 6 on macOS:

    brew install homebrew/dupes/ncurses
    LDFLAGS="-L/usr/local/opt/ncurses/lib" make install
2016-11-24 00:12:43 +09:00
Junegunn Choi
43425158f4 Make escape delay configurable via ncurses standard $ESCDELAY
Also reduce the default delay to 50ms. We should not set it to 0ms as it
breaks escape sequences on WSL. If 50ms is not enough, one can increase
the delay by setting $ESCDELAY to a larger value.
2016-11-23 02:28:03 +09:00
Junegunn Choi
8524ea7441 Do not ignore resize event from ncurses and tcell 2016-11-23 01:58:46 +09:00
12 changed files with 151 additions and 42 deletions

View File

@@ -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

View File

@@ -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=

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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
}

View File

@@ -8,7 +8,7 @@ import (
const (
// Current version
version = "0.15.8"
version = "0.15.9"
// Core
coordinatorDelayMax time.Duration = 100 * time.Millisecond

View File

@@ -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)

View File

@@ -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:

View File

@@ -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:

View File

@@ -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