summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Kelley <michael.kelley@here.com>2016-10-23 20:45:45 -0700
committerJunegunn Choi <junegunn.c@gmail.com>2016-11-07 02:32:14 +0900
commit26895da96918f9b1956a04981c8af5f3e42fcbd8 (patch)
tree189b7c8f639bda4f8d4e5aee838e59be48c69044 /src
parent0c573b3dffe806253e1df2447754a5f3939a11f0 (diff)
Implement tcell-based renderer
Diffstat (limited to 'src')
-rw-r--r--src/history_test.go28
-rw-r--r--src/options_test.go5
-rw-r--r--src/reader.go9
-rw-r--r--src/result_test.go2
-rw-r--r--src/tui/ncurses.go2
-rw-r--r--src/tui/tcell.go523
-rw-r--r--src/tui/termbox.go151
7 files changed, 558 insertions, 162 deletions
diff --git a/src/history_test.go b/src/history_test.go
index fa6f1066..0a014138 100644
--- a/src/history_test.go
+++ b/src/history_test.go
@@ -1,7 +1,10 @@
package fzf
import (
+ "io/ioutil"
+ "os"
"os/user"
+ "runtime"
"testing"
)
@@ -10,23 +13,34 @@ func TestHistory(t *testing.T) {
// Invalid arguments
user, _ := user.Current()
- paths := []string{"/etc", "/proc"}
- if user.Name != "root" {
- paths = append(paths, "/etc/sudoers")
+ var paths []string
+ if runtime.GOOS == "windows" {
+ // GOPATH should exist, so we shouldn't be able to override it
+ paths = []string{os.Getenv("GOPATH")}
+ } else {
+ paths = []string{"/etc", "/proc"}
+ if user.Name != "root" {
+ paths = append(paths, "/etc/sudoers")
+ }
}
+
for _, path := range paths {
if _, e := NewHistory(path, maxHistory); e == nil {
t.Error("Error expected for: " + path)
}
}
+
+ f, _ := ioutil.TempFile("", "fzf-history")
+ f.Close()
+
{ // Append lines
- h, _ := NewHistory("/tmp/fzf-history", maxHistory)
+ h, _ := NewHistory(f.Name(), maxHistory)
for i := 0; i < maxHistory+10; i++ {
h.append("foobar")
}
}
{ // Read lines
- h, _ := NewHistory("/tmp/fzf-history", maxHistory)
+ h, _ := NewHistory(f.Name(), maxHistory)
if len(h.lines) != maxHistory+1 {
t.Errorf("Expected: %d, actual: %d\n", maxHistory+1, len(h.lines))
}
@@ -37,13 +51,13 @@ func TestHistory(t *testing.T) {
}
}
{ // Append lines
- h, _ := NewHistory("/tmp/fzf-history", maxHistory)
+ h, _ := NewHistory(f.Name(), maxHistory)
h.append("barfoo")
h.append("")
h.append("foobarbaz")
}
{ // Read lines again
- h, _ := NewHistory("/tmp/fzf-history", maxHistory)
+ h, _ := NewHistory(f.Name(), maxHistory)
if len(h.lines) != maxHistory+1 {
t.Errorf("Expected: %d, actual: %d\n", maxHistory+1, len(h.lines))
}
diff --git a/src/options_test.go b/src/options_test.go
index f16569e3..092efe4d 100644
--- a/src/options_test.go
+++ b/src/options_test.go
@@ -2,6 +2,7 @@ package fzf
import (
"fmt"
+ "io/ioutil"
"testing"
"github.com/junegunn/fzf/src/tui"
@@ -336,7 +337,9 @@ func TestDefaultCtrlNP(t *testing.T) {
check([]string{"--bind=ctrl-n:accept"}, tui.CtrlN, actAccept)
check([]string{"--bind=ctrl-p:accept"}, tui.CtrlP, actAccept)
- hist := "--history=/tmp/fzf-history"
+ f, _ := ioutil.TempFile("", "fzf-history")
+ f.Close()
+ hist := "--history=" + f.Name()
check([]string{hist}, tui.CtrlN, actNextHistory)
check([]string{hist}, tui.CtrlP, actPreviousHistory)
diff --git a/src/reader.go b/src/reader.go
index 05426660..15a0f44e 100644
--- a/src/reader.go
+++ b/src/reader.go
@@ -4,6 +4,7 @@ import (
"bufio"
"io"
"os"
+ "runtime"
"github.com/junegunn/fzf/src/util"
)
@@ -39,9 +40,15 @@ func (r *Reader) feed(src io.Reader) {
// ReadBytes returns err != nil if and only if the returned data does not
// end in delim.
bytea, err := reader.ReadBytes(delim)
+ byteaLen := len(bytea)
if len(bytea) > 0 {
if err == nil {
- bytea = bytea[:len(bytea)-1]
+ // get rid of carriage return if under Windows:
+ if runtime.GOOS == "windows" && byteaLen >= 2 && bytea[byteaLen-2] == byte('\r') {
+ bytea = bytea[:byteaLen-2]
+ } else {
+ bytea = bytea[:byteaLen-1]
+ }
}
if r.pusher(bytea) {
r.eventBox.Set(EvtReadNew, nil)
diff --git a/src/result_test.go b/src/result_test.go
index 06402c1b..15b1bdbb 100644
--- a/src/result_test.go
+++ b/src/result_test.go
@@ -1,4 +1,4 @@
-// +build !termbox
+// +build !tcell
package fzf
diff --git a/src/tui/ncurses.go b/src/tui/ncurses.go
index 7a443407..3f52f3f8 100644
--- a/src/tui/ncurses.go
+++ b/src/tui/ncurses.go
@@ -1,5 +1,5 @@
// +build !windows
-// +build !termbox
+// +build !tcell
package tui
diff --git a/src/tui/tcell.go b/src/tui/tcell.go
new file mode 100644
index 00000000..591b366c
--- /dev/null
+++ b/src/tui/tcell.go
@@ -0,0 +1,523 @@
+// +build tcell windows
+
+package tui
+
+import (
+ "time"
+ "unicode/utf8"
+
+ "fmt"
+ "os"
+
+ "runtime"
+
+ "github.com/gdamore/tcell"
+ "github.com/gdamore/tcell/encoding"
+)
+
+type ColorPair [2]Color
+
+func (p ColorPair) fg() Color {
+ return p[0]
+}
+
+func (p ColorPair) bg() Color {
+ return p[1]
+}
+
+func (p ColorPair) style() tcell.Style {
+ style := tcell.StyleDefault
+ return style.Foreground(tcell.Color(p.fg())).Background(tcell.Color(p.bg()))
+}
+
+type Attr tcell.Style
+
+type WindowTcell struct {
+ LastX int
+ LastY int
+ MoveCursor bool
+ Border bool
+}
+type WindowImpl WindowTcell
+
+const (
+ Bold = Attr(tcell.AttrBold)
+ Dim = Attr(tcell.AttrDim)
+ Blink = Attr(tcell.AttrBlink)
+ Reverse = Attr(tcell.AttrReverse)
+ Underline = Attr(tcell.AttrUnderline)
+)
+
+const (
+ AttrRegular Attr = 0
+)
+
+var (
+ ColDefault = ColorPair{colDefault, colDefault}
+ ColNormal ColorPair
+ ColPrompt ColorPair
+ ColMatch ColorPair
+ ColCurrent ColorPair
+ ColCurrentMatch ColorPair
+ ColSpinner ColorPair
+ ColInfo ColorPair
+ ColCursor ColorPair
+ ColSelected ColorPair
+ ColHeader ColorPair
+ ColBorder ColorPair
+ ColUser ColorPair
+)
+
+func DefaultTheme() *ColorTheme {
+ if _screen.Colors() >= 256 {
+ return Dark256
+ }
+ return Default16
+}
+
+func PairFor(fg Color, bg Color) ColorPair {
+ return [2]Color{fg, bg}
+}
+
+var (
+ _colorToAttribute = []tcell.Color{
+ tcell.ColorBlack,
+ tcell.ColorRed,
+ tcell.ColorGreen,
+ tcell.ColorYellow,
+ tcell.ColorBlue,
+ tcell.ColorDarkMagenta,
+ tcell.ColorLightCyan,
+ tcell.ColorWhite,
+ }
+)
+
+func (c Color) Style() tcell.Color {
+ if c <= colDefault {
+ return tcell.ColorDefault
+ } else if c >= colBlack && c <= colWhite {
+ return _colorToAttribute[int(c)]
+ } else {
+ return tcell.Color(c)
+ }
+}
+
+func (a Attr) Merge(b Attr) Attr {
+ return a | b
+}
+
+var (
+ _screen tcell.Screen
+)
+
+func Init(theme *ColorTheme, black bool, mouse bool) {
+ encoding.Register()
+
+ s, e := tcell.NewScreen()
+ if e != nil {
+ fmt.Fprintf(os.Stderr, "%v\n", e)
+ os.Exit(1)
+ }
+ if e = s.Init(); e != nil {
+ fmt.Fprintf(os.Stderr, "%v\n", e)
+ os.Exit(1)
+ }
+ _screen = s
+
+ _color = theme != nil
+ if _color {
+ InitTheme(theme, black)
+ }
+ ColNormal = ColorPair{theme.Fg, theme.Bg}
+ ColPrompt = ColorPair{theme.Prompt, theme.Bg}
+ ColMatch = ColorPair{theme.Match, theme.Bg}
+ ColCurrent = ColorPair{theme.Current, theme.DarkBg}
+ ColCurrentMatch = ColorPair{theme.CurrentMatch, theme.DarkBg}
+ ColSpinner = ColorPair{theme.Spinner, theme.Bg}
+ ColInfo = ColorPair{theme.Info, theme.Bg}
+ ColCursor = ColorPair{theme.Cursor, theme.DarkBg}
+ ColSelected = ColorPair{theme.Selected, theme.DarkBg}
+ ColHeader = ColorPair{theme.Header, theme.Bg}
+ ColBorder = ColorPair{theme.Border, theme.Bg}
+
+ if mouse {
+ _screen.EnableMouse()
+ } else {
+ _screen.DisableMouse()
+ }
+}
+
+func MaxX() int {
+ ncols, _ := _screen.Size()
+ return int(ncols)
+}
+
+func MaxY() int {
+ _, nlines := _screen.Size()
+ return int(nlines)
+}
+
+func (w *Window) win() *WindowTcell {
+ return (*WindowTcell)(w.impl)
+}
+
+func Clear() {
+ _screen.Clear()
+}
+
+func Refresh() {
+ // noop
+}
+
+func GetChar() Event {
+ ev := _screen.PollEvent()
+ switch ev := ev.(type) {
+ case *tcell.EventResize:
+ return Event{Invalid, 0, nil}
+
+ // process mouse events:
+ case *tcell.EventMouse:
+ x, y := ev.Position()
+ button := ev.Buttons()
+ mod := ev.Modifiers() != 0
+ if button&tcell.WheelDown != 0 {
+ return Event{Mouse, 0, &MouseEvent{y, x, -1, false, false, mod}}
+ } else if button&tcell.WheelUp != 0 {
+ return Event{Mouse, 0, &MouseEvent{y, x, +1, false, false, mod}}
+ } else if runtime.GOOS != "windows" {
+ // double and single taps on Windows don't quite work due to
+ // the console acting on the events and not allowing us
+ // to consume them.
+
+ down := button&tcell.Button1 != 0 // left
+ double := false
+ if down {
+ now := time.Now()
+ if now.Sub(_prevDownTime) < doubleClickDuration {
+ _clickY = append(_clickY, x)
+ } else {
+ _clickY = []int{x}
+ }
+ _prevDownTime = now
+ } else {
+ if len(_clickY) > 1 && _clickY[0] == _clickY[1] &&
+ time.Now().Sub(_prevDownTime) < doubleClickDuration {
+ double = true
+ }
+ }
+
+ return Event{Mouse, 0, &MouseEvent{y, x, 0, down, double, mod}}
+ }
+
+ // process keyboard:
+ case *tcell.EventKey:
+ switch ev.Key() {
+ case tcell.KeyCtrlA:
+ return Event{CtrlA, 0, nil}
+ case tcell.KeyCtrlB:
+ return Event{CtrlB, 0, nil}
+ case tcell.KeyCtrlC:
+ return Event{CtrlC, 0, nil}
+ case tcell.KeyCtrlD:
+ return Event{CtrlD, 0, nil}
+ case tcell.KeyCtrlE:
+ return Event{CtrlE, 0, nil}
+ case tcell.KeyCtrlF:
+ return Event{CtrlF, 0, nil}
+ case tcell.KeyCtrlG:
+ return Event{CtrlG, 0, nil}
+ case tcell.KeyCtrlJ:
+ return Event{CtrlJ, 0, nil}
+ case tcell.KeyCtrlK:
+ return Event{CtrlK, 0, nil}
+ case tcell.KeyCtrlL:
+ return Event{CtrlL, 0, nil}
+ case tcell.KeyCtrlM:
+ return Event{CtrlM, 0, nil}
+ case tcell.KeyCtrlN:
+ return Event{CtrlN, 0, nil}
+ case tcell.KeyCtrlO:
+ return Event{CtrlO, 0, nil}
+ case tcell.KeyCtrlP:
+ return Event{CtrlP, 0, nil}
+ case tcell.KeyCtrlQ:
+ return Event{CtrlQ, 0, nil}
+ case tcell.KeyCtrlR:
+ return Event{CtrlR, 0, nil}
+ case tcell.KeyCtrlS:
+ return Event{CtrlS, 0, nil}
+ case tcell.KeyCtrlT:
+ return Event{CtrlT, 0, nil}
+ case tcell.KeyCtrlU:
+ return Event{CtrlU, 0, nil}
+ case tcell.KeyCtrlV:
+ return Event{CtrlV, 0, nil}
+ case tcell.KeyCtrlW:
+ return Event{CtrlW, 0, nil}
+ case tcell.KeyCtrlX:
+ return Event{CtrlX, 0, nil}
+ case tcell.KeyCtrlY:
+ return Event{CtrlY, 0, nil}
+ case tcell.KeyCtrlZ:
+ return Event{CtrlZ, 0, nil}
+ case tcell.KeyBackspace, tcell.KeyBackspace2:
+ return Event{BSpace, 0, nil}
+
+ case tcell.KeyUp:
+ return Event{Up, 0, nil}
+ case tcell.KeyDown:
+ return Event{Down, 0, nil}
+ case tcell.KeyLeft:
+ return Event{Left, 0, nil}
+ case tcell.KeyRight:
+ return Event{Right, 0, nil}
+
+ case tcell.KeyHome:
+ return Event{Home, 0, nil}
+ case tcell.KeyDelete:
+ return Event{Del, 0, nil}
+ case tcell.KeyEnd:
+ return Event{End, 0, nil}
+ /*case tcell.KeyPgUp:
+ return Event{PgUp, 0, nil}
+ case tcell.KeyPgdn:
+ return Event{PgDn, 0, nil}*/
+
+ case tcell.KeyTab:
+ return Event{Tab, 0, nil}
+
+ case tcell.KeyF1:
+ return Event{F1, 0, nil}
+ case tcell.KeyF2:
+ return Event{F2, 0, nil}
+ case tcell.KeyF3:
+ return Event{F3, 0, nil}
+ case tcell.KeyF4:
+ return Event{F4, 0, nil}
+ case tcell.KeyF5:
+ return Event{F5, 0, nil}
+ case tcell.KeyF6:
+ return Event{F6, 0, nil}
+ case tcell.KeyF7:
+ return Event{F7, 0, nil}
+ case tcell.KeyF8:
+ return Event{F8, 0, nil}
+ case tcell.KeyF9:
+ return Event{F9, 0, nil}
+ case tcell.KeyF10:
+ return Event{F10, 0, nil}
+ case tcell.KeyF11:
+ return Event{Invalid, 0, nil}
+ case tcell.KeyF12:
+ return Event{Invalid, 0, nil}
+
+ // ev.Ch doesn't work for some reason for space:
+ case tcell.KeyRune:
+ return Event{Rune, ev.Rune(), nil}
+
+ case tcell.KeyEsc:
+ return Event{ESC, 0, nil}
+
+ }
+ }
+
+ return Event{Invalid, 0, nil}
+}
+
+func Pause() {
+ // TODO
+}
+
+func Close() {
+ _screen.Fini()
+}
+
+func RefreshWindows(windows []*Window) {
+ // TODO
+ for _, w := range windows {
+ if w.win().MoveCursor {
+ _screen.ShowCursor(w.Left+w.win().LastX, w.Top+w.win().LastY)
+ w.win().MoveCursor = false
+ }
+ w.win().LastX = 0
+ w.win().LastY = 0
+ if w.win().Border {
+ w.DrawBorder()
+ }
+ }
+ _screen.Show()
+}
+
+func NewWindow(top int, left int, width int, height int, border bool) *Window {
+ // TODO
+ win := new(WindowTcell)
+ win.Border = border
+ return &Window{
+ impl: (*WindowImpl)(win),
+ Top: top,
+ Left: left,
+ Width: width,
+ Height: height,
+ }
+}
+
+func (w *Window) Close() {
+ // TODO
+}
+
+func fill(x, y, w, h int, r rune) {
+ for ly := 0; ly <= h; ly++ {
+ for lx := 0; lx <= w; lx++ {
+ _screen.SetContent(x+lx, y+ly, r, nil, ColDefault.style())
+ }
+ }
+}
+
+func (w *Window) Erase() {
+ // TODO
+ fill(w.Left, w.Top, w.Width, w.Height, ' ')
+}
+
+func (w *Window) Enclose(y int, x int) bool {
+ return x >= w.Left && x <= (w.Left+w.Width) &&
+ y >= w.Top && y <= (w.Top+w.Height)
+}
+
+func (w *Window) Move(y int, x int) {
+ w.win().LastX = x
+ w.win().LastY = y
+ w.win().MoveCursor = true
+}
+
+func (w *Window) MoveAndClear(y int, x int) {
+ w.Move(y, x)
+ r, _ := utf8.DecodeRuneInString(" ")
+ for i := w.win().LastX; i < w.Width; i++ {
+ _screen.SetContent(i+w.Left, w.win().LastY+w.Top, r, nil, ColDefault.style())
+ }
+ w.win().LastX = 0
+}
+
+func (w *Window) Print(text string) {
+ w.PrintString(text, ColDefault, 0)
+}
+
+func (w *Window) PrintString(text string, pair ColorPair, a Attr) {
+ t := text
+ lx := 0
+
+ // TODO respect attr
+ style := pair.style().
+ Blink(a&Attr(tcell.AttrBlink) != 0).
+ Bold(a&Attr(tcell.AttrBold) != 0).
+ Dim(a&Attr(tcell.AttrDim) != 0).
+ Reverse(a&Attr(tcell.AttrReverse) != 0).
+ Underline(a&Attr(tcell.AttrUnderline) != 0)
+
+ for {
+ if len(t) == 0 {
+ break
+ }
+ r, size := utf8.DecodeRuneInString(t)
+ t = t[size:]
+
+ if r < rune(' ') { // ignore control characters
+ continue
+ }
+
+ if r == '\n' {
+ w.win().LastY++
+ lx = 0
+ } else {
+
+ if r == '\u000D' { // skip carriage return
+ continue
+ }
+
+ var xPos = w.Left + w.win().LastX + lx
+ var yPos = w.Top + w.win().LastY
+ if xPos < (w.Left+w.Width) && yPos < (w.Top+w.Height) {
+ _screen.SetContent(xPos, yPos, r, nil, style)
+ }
+ lx++
+ }
+ }
+ w.win().LastX += lx
+}
+
+func (w *Window) CPrint(pair ColorPair, a Attr, text string) {
+ w.PrintString(text, pair, a)
+}
+
+func (w *Window) FillString(text string, pair ColorPair, a Attr) bool {
+ lx := 0
+
+ //TODO: respect attr
+ style := pair.style().
+ Blink(a&Attr(tcell.AttrBlink) != 0).
+ Bold(a&Attr(tcell.AttrBold) != 0).
+ Dim(a&Attr(tcell.AttrDim) != 0).
+ Reverse(a&Attr(tcell.AttrReverse) != 0).
+ Underline(a&Attr(tcell.AttrUnderline) != 0)
+
+ for _, r := range text {
+ if r == '\n' {
+ w.win().LastY++
+ w.win().LastX = 0
+ lx = 0
+ } else {
+ var xPos = w.Left + w.win().LastX + lx
+
+ // word wrap:
+ if xPos > (w.Left + w.Width) {
+ w.win().LastY++
+ w.win().LastX = 0
+ lx = 0
+ xPos = w.Left
+ }
+ var yPos = w.Top + w.win().LastY
+
+ if yPos >= (w.Top + w.Height) {
+ return false
+ }
+
+ _screen.SetContent(xPos, yPos, r, nil, style)
+ lx++
+ }
+ }
+ w.win().LastX += lx
+
+ return true
+}
+
+func (w *Window) Fill(str string) bool {
+ return w.FillString(str, ColDefault, 0)
+}
+
+func (w *Window) CFill(str string, fg Color, bg Color, a Attr) bool {
+ return w.FillString(str, ColorPair{fg, bg}, a)
+}
+
+func (w *Window) DrawBorder() {
+ left := w.Left
+ right := left + w.Width
+ top := w.Top
+ bot := top + w.Height
+
+ style := ColBorder.style()
+
+ for x := left; x < right; x++ {
+ _screen.SetContent(x, top, tcell.RuneHLine, nil, style)
+ _screen.SetContent(x, bot-1, tcell.RuneHLine, nil, style)
+ }
+
+ for y := top; y < bot; y++ {
+ _screen.SetContent(left, y, tcell.RuneVLine, nil, style)
+ _screen.SetContent(right-1, y, tcell.RuneVLine, nil, style)
+ }
+
+ _screen.SetContent(left, top, tcell.RuneULCorner, nil, style)
+ _screen.SetContent(right-1, top, tcell.RuneURCorner, nil, style)
+ _screen.SetContent(left, bot-1, tcell.RuneLLCorner, nil, style)
+ _screen.SetContent(right-1, bot-1, tcell.RuneLRCorner, nil, style)
+}
diff --git a/src/tui/termbox.go b/src/tui/termbox.go
deleted file mode 100644
index c49512ce..00000000
--- a/src/tui/termbox.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// +build termbox windows
-
-package tui
-
-import (
- "github.com/nsf/termbox-go"
-)
-
-type ColorPair [2]Color
-type Attr uint16
-type WindowImpl int // FIXME
-
-const (
- // TODO
- _ = iota
- Bold
- Dim
- Blink
- Reverse
- Underline
-)
-
-const (
- AttrRegular Attr = 0
-)
-
-var (
- ColDefault = ColorPair{colDefault, colDefault}
- ColNormal ColorPair
- ColPrompt ColorPair
- ColMatch ColorPair
- ColCurrent ColorPair
- ColCurrentMatch ColorPair
- ColSpinner ColorPair
- ColInfo ColorPair
- ColCursor ColorPair
- ColSelected ColorPair
- ColHeader ColorPair
- ColBorder ColorPair
- ColUser ColorPair
-)
-
-func DefaultTheme() *ColorTheme {
- if termbox.SetOutputMode(termbox.OutputCurrent) == termbox.Output256 {
- return Dark256
- }
- return Default16
-}
-
-func PairFor(fg Color, bg Color) ColorPair {
- return [2]Color{fg, bg}
-}
-
-func (a Attr) Merge(b Attr) Attr {
- return a | b
-}
-
-func Init(theme *ColorTheme, black bool, mouse bool) {
- ColNormal = ColorPair{theme.Fg, theme.Bg}
- ColPrompt = ColorPair{theme.Prompt, theme.Bg}
- ColMatch = ColorPair{theme.Match, theme.Bg}
- ColCurrent = ColorPair{theme.Current, theme.DarkBg}
- ColCurrentMatch = ColorPair{theme.CurrentMatch, theme.DarkBg}
- ColSpinner = ColorPair{theme.Spinner, theme.Bg}
- ColInfo = ColorPair{theme.Info, theme.Bg}
- ColCursor = ColorPair{theme.Cursor, theme.DarkBg}
- ColSelected = ColorPair{theme.Selected, theme.DarkBg}
- ColHeader = ColorPair{theme.Header, theme.Bg}
- ColBorder = ColorPair{theme.Border, theme.Bg}
-
- // TODO
-}
-
-func MaxX() int {
- // TODO
- return 80
-}
-
-func MaxY() int {
- // TODO
- return 24
-}
-
-func Clear() {
- // TODO
-}
-
-func Refresh() {
- // TODO
-}
-
-func GetChar() Event {
- // TODO
- return Event{}
-}
-
-func Pause() {
- // TODO
-}
-
-func Close() {
- // TODO
-}
-
-func RefreshWindows(windows []*Window) {
- // TODO
-}
-
-func NewWindow(top int, left int, width int, height int, border bool) *Window {
- // TODO
- return &Window{}
-}
-
-func (w *Window) Close() {
- // TODO
-}
-
-func (w *Window) Erase() {
- // TODO
-}
-
-func (w *Window) Enclose(y int, x int) bool {
- // TODO
- return false
-}
-
-func (w *Window) Move(y int, x int) {
- // TODO
-}
-
-func (w *Window) MoveAndClear(y int, x int) {
- // TODO
-}
-
-func (w *Window) Print(text string) {
- // TODO
-}
-
-func (w *Window) CPrint(pair ColorPair, a Attr, text string) {
- // TODO
-}
-
-func (w *Window) Fill(str string) bool {
- // TODO
- return false
-}
-
-func (w *Window) CFill(str string, fg Color, bg Color, a Attr) bool {
- // TODO
- return false
-}