2020-01-28 07:18:19 +03:00
|
|
|
module term
|
|
|
|
|
2020-01-28 22:25:17 +03:00
|
|
|
import os
|
2020-01-28 07:18:19 +03:00
|
|
|
|
2020-01-28 22:25:17 +03:00
|
|
|
#include <sys/ioctl.h>
|
2020-03-31 13:46:46 +03:00
|
|
|
#include <termios.h> // TIOCGWINSZ
|
2020-01-28 22:25:17 +03:00
|
|
|
pub struct C.winsize {
|
|
|
|
pub:
|
|
|
|
ws_row u16
|
|
|
|
ws_col u16
|
|
|
|
ws_xpixel u16
|
|
|
|
ws_ypixel u16
|
2020-01-28 07:18:19 +03:00
|
|
|
}
|
|
|
|
|
2020-01-28 22:25:17 +03:00
|
|
|
fn C.ioctl(fd int, request u64, arg voidptr) int
|
2020-01-28 07:18:19 +03:00
|
|
|
|
2020-01-29 07:12:12 +03:00
|
|
|
// get_terminal_size returns a number of colums and rows of terminal window.
|
2020-09-08 22:00:10 +03:00
|
|
|
pub fn get_terminal_size() (int, int) {
|
2020-01-28 22:25:17 +03:00
|
|
|
if is_atty(1) <= 0 || os.getenv('TERM') == 'dumb' {
|
2020-01-29 07:12:12 +03:00
|
|
|
return default_columns_size, default_rows_size
|
2020-01-28 22:25:17 +03:00
|
|
|
}
|
|
|
|
w := C.winsize{}
|
2020-01-29 07:12:12 +03:00
|
|
|
C.ioctl(1, C.TIOCGWINSZ, &w)
|
2020-09-08 22:00:10 +03:00
|
|
|
return int(w.ws_col), int(w.ws_row)
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_cursor_position returns a Coord containing the current cursor position
|
|
|
|
pub fn get_cursor_position() Coord {
|
|
|
|
if is_atty(1) <= 0 || os.getenv('TERM') == 'dumb' {
|
|
|
|
return Coord{
|
|
|
|
x: 0
|
|
|
|
y: 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// TODO: use termios.h, C.tcgetattr & C.tcsetattr directly,
|
|
|
|
// instead of using `stty`
|
|
|
|
oldsettings := os.exec('stty -g') or {
|
|
|
|
os.Result{}
|
|
|
|
}
|
|
|
|
os.system('stty -echo -icanon time 0')
|
|
|
|
print('\033[6n')
|
|
|
|
mut ch := int(0)
|
|
|
|
mut i := 0
|
|
|
|
// ESC [ YYY `;` XXX `R`
|
|
|
|
mut reading_x := false
|
|
|
|
mut reading_y := false
|
|
|
|
mut x := 0
|
|
|
|
mut y := 0
|
|
|
|
for {
|
|
|
|
ch = C.getchar()
|
|
|
|
b := byte(ch)
|
|
|
|
i++
|
2020-10-21 08:49:07 +03:00
|
|
|
if i >= 15 {
|
|
|
|
panic('C.getchar() called too many times')
|
|
|
|
}
|
2020-09-08 22:00:10 +03:00
|
|
|
// state management:
|
|
|
|
if b == `R` {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if b == `[` {
|
|
|
|
reading_y = true
|
|
|
|
reading_x = false
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if b == `;` {
|
|
|
|
reading_y = false
|
|
|
|
reading_x = true
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// converting string vals to ints:
|
|
|
|
if reading_x {
|
|
|
|
x *= 10
|
|
|
|
x += (b - byte(`0`))
|
|
|
|
}
|
|
|
|
if reading_y {
|
|
|
|
y *= 10
|
|
|
|
y += (b - byte(`0`))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// restore the old terminal settings:
|
|
|
|
os.system('stty $oldsettings.output')
|
|
|
|
return Coord{
|
|
|
|
x: x
|
|
|
|
y: y
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set_terminal_title change the terminal title
|
|
|
|
pub fn set_terminal_title(title string) bool {
|
|
|
|
if is_atty(1) <= 0 || os.getenv('TERM') == 'dumb' {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
print('\033]0;${title}\007')
|
|
|
|
return true
|
2020-01-28 07:18:19 +03:00
|
|
|
}
|
2021-02-09 15:25:31 +03:00
|
|
|
|
|
|
|
// clear clears current terminal screen.
|
|
|
|
pub fn clear() {
|
|
|
|
print('\x1b[2J')
|
|
|
|
print('\x1b[H')
|
|
|
|
}
|