package main import "github.com/nsf/termbox-go" import "github.com/mattn/go-runewidth" import "github.com/atotto/clipboard" import "os" type Point struct { X int Y int } func fill(lt Point, rb Point, sym rune) { if (rb.Y < lt.Y) || (rb.X < lt.X) { return } var x, y int for x = lt.X; x <= rb.X; x++ { for y = lt.Y; y <= rb.Y; y++ { content[x][y] = sym } } } func setContent(x, y int, msg string) { for _, c := range msg { content[x][y] = c x += runewidth.RuneWidth(c) } } var ltSel, rbSel Point var content [][]rune func clearSel() { ltSel = Point{-1, -1} rbSel = Point{-1, -1} } func redraw() { var w, h int = termbox.Size() var x, y int for x = 0; x < w; x++ { for y = 0; y < h; y++ { var c rune = content[x][y] if x >= ltSel.X && x <= rbSel.X && y >= ltSel.Y && y <= rbSel.Y { termbox.SetCell(x, y, c, termbox.ColorDefault|termbox.AttrReverse, termbox.ColorDefault) } else { termbox.SetCell(x, y, c, termbox.ColorDefault, termbox.ColorDefault) } } } termbox.Flush() } func addToSel(x int, y int) { if ltSel.X == -1 { ltSel = Point{x, y} } else if x < ltSel.X && y < ltSel.Y { rbSel = ltSel ltSel = Point{x, y} } else { rbSel = Point{x, y} } } func copySel() { var x, y int if ltSel.X < 0 || rbSel.X < 0 { return } var cb string = "" // here we have to go line by line to combine everything for y = ltSel.Y; y <= rbSel.Y; y++ { for x = ltSel.X; x <= rbSel.X; x++ { cb += string(content[x][y]) } } clipboard.WriteAll(cb) } func clearScreen() { var w, h int = termbox.Size() content = make([][]rune, w) var x, y int for x = 0; x < w; x++ { content[x] = make([]rune, h) for y = 0; y < h; y++ { content[x][y] = ' ' } } } func main() { termbox.Init() clearSel() clearScreen() termbox.SetInputMode(termbox.InputEsc | termbox.InputMouse) setContent(10, 10, "Error: Could not connect: ") setContent(10, 11, "dial tcp 127.0.0.1:3306:") setContent(10, 12, "connect: connection refused") setContent(22, 14, " OK ") fill(Point{8, 8}, Point{38, 8}, 'x') fill(Point{8, 16}, Point{38, 16}, 'x') fill(Point{7, 8}, Point{7, 16}, 'x') fill(Point{39, 8}, Point{39, 16}, 'x') redraw() for { ev := termbox.PollEvent() switch ev.Type { case termbox.EventMouse: addToSel(ev.MouseX, ev.MouseY) case termbox.EventKey: if ev.Key == termbox.KeyEnter { copySel() clearSel() } else { termbox.Close() os.Exit(0) } } redraw() } }