diff --git a/internal/editor/editor.go b/internal/editor/editor.go index 8142232..717ecff 100644 --- a/internal/editor/editor.go +++ b/internal/editor/editor.go @@ -1,9 +1,6 @@ package editor import ( - "bufio" - "os" - "timshome.page/gilo/internal/char" "timshome.page/gilo/internal/terminal" ) @@ -13,19 +10,10 @@ type Editor struct { cols int } -var reader = bufio.NewReader(os.Stdin) - -func readKey() (rune, int) { - ch, size, err := reader.ReadRune() - if err != nil { - panic(err) - } - - return ch, size -} - func drawRows() { - for y :=0; y < 24; y += 1 { + _, rows := terminal.Size() + + for y :=0; y < rows; y += 1 { terminal.OutLn("~") } } @@ -40,7 +28,7 @@ func RefreshScreen() { } func ProcessKeypress() bool { - ch, _ := readKey() + ch, _ := terminal.ReadKey() // Clean up on exit if ch == char.Ctrl('q') { diff --git a/internal/terminal/terminal.go b/internal/terminal/terminal.go index 4d48483..bce1f20 100644 --- a/internal/terminal/terminal.go +++ b/internal/terminal/terminal.go @@ -1,6 +1,7 @@ package terminal import ( + "bufio" "fmt" "os" @@ -10,6 +11,17 @@ import ( const ClearScreen = "2J" const ResetCursor = "H" +var reader = bufio.NewReader(os.Stdin) + +func ReadKey() (rune, int) { + ch, size, err := reader.ReadRune() + if err != nil { + panic(err) + } + + return ch, size +} + // Is this a valid interactive terminal? func check() { if !term.IsTerminal(int(os.Stdin.Fd())) { @@ -41,13 +53,52 @@ func ANSICode (code string) { fmt.Printf("\x1b[%s", code) } -func Size () (width int, height int) { - width, height, err := term.GetSize(int(os.Stdin.Fd())) - if err != nil { - width = 80 - height = 24 +func sizeTrick () (rows int, cols int) { + // Move cursor to location further than likely screen size + // The cursor will move to maximum available position + fmt.Print("\x1b[999C\x1b[99B") + + // Ask the terminal where the cursor is + fmt.Print("\x1b[6n") + + // Read stdin looking for the reported location + buffer := "" + for char, _ := ReadKey(); char != 'R'; char, _ = ReadKey() { + + if char == '\x1b' || char == '[' { + continue + } + + if char == 'R' || char == '\x00'{ + break + } + + buffer += string(char) } + _, err := fmt.Sscanf(buffer, "%d;%d", &rows, &cols) + if err != nil { + panic(err) + } + + return rows, cols +} + +func Size () (width int, height int) { + width = 80 + height = 24 + + // Try the syscall first + width, height, err := term.GetSize(int(os.Stdin.Fd())) + if err == nil { + return width, height + } + + // Figure out the size the hard way + height, width = sizeTrick() + + OutLn("%d Rows, %d Cols", height, width) + return width, height }