summaryrefslogtreecommitdiff
path: root/src/tui/light_unix.go
diff options
context:
space:
mode:
authorMichael Kelley <michael.a.kelley@gmail.com>2019-02-04 22:51:39 -0800
committerJunegunn Choi <junegunn.c@gmail.com>2020-03-10 00:03:34 +0900
commit7d5985baf927cdd04070679cbfbb5ff6b0728f6d (patch)
tree5b67c8ac90f2a040832c1d17b1ed10746f1d6b36 /src/tui/light_unix.go
parent7c40a424c0bf5a8967816d51ead6a71a334f30bb (diff)
downloadfzf-7d5985baf927cdd04070679cbfbb5ff6b0728f6d.tar.gz
Make height option work under Windows (#1341)
Separate Unix & Windows code into platform specific files for light renderer
Diffstat (limited to 'src/tui/light_unix.go')
-rw-r--r--src/tui/light_unix.go97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/tui/light_unix.go b/src/tui/light_unix.go
new file mode 100644
index 00000000..e4ce6313
--- /dev/null
+++ b/src/tui/light_unix.go
@@ -0,0 +1,97 @@
+// +build !windows
+
+package tui
+
+import (
+ "fmt"
+ "os"
+ "syscall"
+
+ "github.com/junegunn/fzf/src/util"
+ "golang.org/x/crypto/ssh/terminal"
+)
+
+func IsLightRendererSupported() bool {
+ return true
+}
+
+func (r *LightRenderer) fd() int {
+ return int(r.ttyin.Fd())
+}
+
+func (r *LightRenderer) initPlatform() error {
+ fd := r.fd()
+ origState, err := terminal.GetState(fd)
+ if err != nil {
+ return err
+ }
+ r.origState = origState
+ terminal.MakeRaw(fd)
+ return nil
+}
+
+func (r *LightRenderer) closePlatform() {
+ // NOOP
+}
+
+func openTtyIn() *os.File {
+ in, err := os.OpenFile(consoleDevice, syscall.O_RDONLY, 0)
+ if err != nil {
+ tty := ttyname()
+ if len(tty) > 0 {
+ if in, err := os.OpenFile(tty, syscall.O_RDONLY, 0); err == nil {
+ return in
+ }
+ }
+ fmt.Fprintln(os.Stderr, "Failed to open "+consoleDevice)
+ os.Exit(2)
+ }
+ return in
+}
+
+func (r *LightRenderer) setupTerminal() {
+ terminal.MakeRaw(r.fd())
+}
+
+func (r *LightRenderer) restoreTerminal() {
+ terminal.Restore(r.fd(), r.origState)
+}
+
+func (r *LightRenderer) updateTerminalSize() {
+ width, height, err := terminal.GetSize(r.fd())
+
+ if err == nil {
+ r.width = width
+ r.height = r.maxHeightFunc(height)
+ } else {
+ r.width = getEnv("COLUMNS", defaultWidth)
+ r.height = r.maxHeightFunc(getEnv("LINES", defaultHeight))
+ }
+}
+
+func (r *LightRenderer) findOffset() (row int, col int) {
+ r.csi("6n")
+ r.flush()
+ bytes := []byte{}
+ for tries := 0; tries < offsetPollTries; tries++ {
+ bytes = r.getBytesInternal(bytes, tries > 0)
+ offsets := offsetRegexp.FindSubmatch(bytes)
+ if len(offsets) > 3 {
+ // Add anything we skipped over to the input buffer
+ r.buffer = append(r.buffer, offsets[1]...)
+ return atoi(string(offsets[2]), 0) - 1, atoi(string(offsets[3]), 0) - 1
+ }
+ }
+ return -1, -1
+}
+
+func (r *LightRenderer) getch(nonblock bool) (int, bool) {
+ b := make([]byte, 1)
+ fd := r.fd()
+ util.SetNonblock(r.ttyin, nonblock)
+ _, err := util.Read(fd, b)
+ if err != nil {
+ return 0, false
+ }
+ return int(b[0]), true
+}