func main() { s, err := gc.Init() if err != nil { log.Fatal("init:", err) } defer gc.End() gc.Cursor(0) s.Move(20, 0) s.Print("Key check in ") for i := 3; i >= 1; i-- { s.MovePrint(20, 13, i) s.Refresh() time.Sleep(500 * time.Millisecond) } s.Println() gc.Echo(false) // task requirement next two lines s.Timeout(0) k := s.GetChar() if k == 0 { s.Println("No key pressed") } else { s.Println("You pressed", gc.KeyString(k)) } s.Refresh() s.Timeout(-1) gc.FlushInput() gc.Cursor(1) s.GetChar() }
func (cw *chatWin) handleInput(win *goncurses.Window) (line string) { k := win.GetChar() if k == 0 { return "" } // some systems send a DEL ASCII character instead of KEY_BACKSPACE // account for both just in case if k == 127 { k = goncurses.KEY_BACKSPACE } switch k { case goncurses.KEY_TAB: // tab // case goncurses.KEY_RETURN: // enter key vs. KEY_ENTER case goncurses.KEY_DOWN: // down arrow key case goncurses.KEY_UP: // up arrow key case goncurses.KEY_LEFT: // left arrow key case goncurses.KEY_RIGHT: // right arrow key case goncurses.KEY_HOME: // home key case goncurses.KEY_BACKSPACE: // backpace if len(cw.line) > 0 { cw.line = cw.line[:len(cw.line)-1] } y, x := win.CursorYX() // TODO: handle this more elegantly (e.g. tell ncurses not to print backspaces) // we have to do this three times because ncurses inserts two characters for backspace // this is likely wrong in some cases for i := 0; i < 3; i++ { y, x = cw.moveLeft(y, x) win.MoveDelChar(y, x) } win.Refresh() case goncurses.KEY_F1: // F1 key case goncurses.KEY_F2: // F2 key case goncurses.KEY_F3: // F3 key case goncurses.KEY_F4: // F4 key case goncurses.KEY_F5: // F5 key case goncurses.KEY_F6: // F6 key case goncurses.KEY_F7: // F7 key case goncurses.KEY_F8: // F8 key case goncurses.KEY_F9: // F9 key case goncurses.KEY_F10: // F10 key case goncurses.KEY_F11: // F11 key case goncurses.KEY_F12: // F12 key case goncurses.KEY_DL: // delete-line key case goncurses.KEY_IL: // insert-line key case goncurses.KEY_DC: // delete-character key case goncurses.KEY_IC: // insert-character key case goncurses.KEY_EIC: // sent by rmir or smir in insert mode case goncurses.KEY_CLEAR: // clear-screen or erase key3 case goncurses.KEY_EOS: // clear-to-end-of-screen key case goncurses.KEY_EOL: // clear-to-end-of-line key case goncurses.KEY_SF: // scroll-forward key case goncurses.KEY_SR: // scroll-backward key case goncurses.KEY_PAGEDOWN: // page-down key (next-page) case goncurses.KEY_PAGEUP: // page-up key (prev-page) case goncurses.KEY_STAB: // set-tab key case goncurses.KEY_CTAB: // clear-tab key case goncurses.KEY_CATAB: // clear-all-tabs key case goncurses.KEY_RETURN: // enter key vs. KEY_ENTER fallthrough case goncurses.KEY_ENTER: // enter/send key line = cw.line cw.line = "" win.Erase() win.Print(PROMPT) case goncurses.KEY_PRINT: // print key case goncurses.KEY_LL: // lower-left key (home down) case goncurses.KEY_A1: // upper left of keypad case goncurses.KEY_A3: // upper right of keypad case goncurses.KEY_B2: // center of keypad case goncurses.KEY_C1: // lower left of keypad case goncurses.KEY_C3: // lower right of keypad case goncurses.KEY_BTAB: // back-tab key case goncurses.KEY_BEG: // begin key case goncurses.KEY_CANCEL: // cancel key case goncurses.KEY_CLOSE: // close key case goncurses.KEY_COMMAND: // command key case goncurses.KEY_COPY: // copy key case goncurses.KEY_CREATE: // create key case goncurses.KEY_END: // end key case goncurses.KEY_EXIT: // exit key case goncurses.KEY_FIND: // find key case goncurses.KEY_HELP: // help key case goncurses.KEY_MARK: // mark key case goncurses.KEY_MESSAGE: // message key case goncurses.KEY_MOVE: // move key case goncurses.KEY_NEXT: // next key case goncurses.KEY_OPEN: // open key case goncurses.KEY_OPTIONS: // options key case goncurses.KEY_PREVIOUS: // previous key case goncurses.KEY_REDO: // redo key case goncurses.KEY_REFERENCE: // reference key case goncurses.KEY_REFRESH: // refresh key case goncurses.KEY_REPLACE: // replace key case goncurses.KEY_RESTART: // restart key case goncurses.KEY_RESUME: // resume key case goncurses.KEY_SAVE: // save key case goncurses.KEY_SBEG: // shifted begin key case goncurses.KEY_SCANCEL: // shifted cancel key case goncurses.KEY_SCOMMAND: // shifted command key case goncurses.KEY_SCOPY: // shifted copy key case goncurses.KEY_SCREATE: // shifted create key case goncurses.KEY_SDC: // shifted delete-character key case goncurses.KEY_SDL: // shifted delete-line key case goncurses.KEY_SELECT: // select key case goncurses.KEY_SEND: // shifted end key case goncurses.KEY_SEOL: // shifted clear-to-end-of-line key case goncurses.KEY_SEXIT: // shifted exit key case goncurses.KEY_SFIND: // shifted find key case goncurses.KEY_SHELP: // shifted help key case goncurses.KEY_SHOME: // shifted home key case goncurses.KEY_SIC: // shifted insert-character key case goncurses.KEY_SLEFT: // shifted left-arrow key case goncurses.KEY_SMESSAGE: // shifted message key case goncurses.KEY_SMOVE: // shifted move key case goncurses.KEY_SNEXT: // shifted next key case goncurses.KEY_SOPTIONS: // shifted options key case goncurses.KEY_SPREVIOUS: // shifted previous key case goncurses.KEY_SPRINT: // shifted print key case goncurses.KEY_SREDO: // shifted redo key case goncurses.KEY_SREPLACE: // shifted replace key case goncurses.KEY_SRIGHT: // shifted right-arrow key case goncurses.KEY_SRSUME: // shifted resume key case goncurses.KEY_SSAVE: // shifted save key case goncurses.KEY_SSUSPEND: // shifted suspend key case goncurses.KEY_SUNDO: // shifted undo key case goncurses.KEY_SUSPEND: // suspend key case goncurses.KEY_UNDO: // undo key case goncurses.KEY_MOUSE: // any mouse event case goncurses.KEY_RESIZE: // Terminal resize event //case goncurses.KEY_EVENT: // We were interrupted by an event case goncurses.KEY_MAX: default: cw.line += goncurses.KeyString(k) } return }
func cli() { var e error scr, e = goncurses.Init() if e != nil { log.Fatal(e) } defer goncurses.End() exit := false pageNum := 0 p := NewPageCache() for !exit { scr.Refresh() h, _ := scr.MaxYX() scr.Clear() height := h - BOTTOM_MARGIN start := height * pageNum end := start + height for end > len(p.Articles) { p.GetNext() } for i, ar := range p.Articles[start:end] { scr.Printf("%d. (%d): %s\n", start+i+1, ar.Karma, ar.Title) } scr.Print("\n(n: next, p: previous, <num>c: view comments, <num>o: open in browser, q: quit) ") scr.Refresh() doneWithInput := false input := "" for !doneWithInput { c := scr.GetChar() if c == 127 { c = goncurses.Key(goncurses.KEY_BACKSPACE) } ch := goncurses.KeyString(c) switch ch { case "c": if num, err := strconv.Atoi(input); err == nil { if num < 1 { doneWithInput = true break } for num-1 > len(p.Articles) { p.GetNext() } text := p.Articles[num-1].PrintComments() line := 0 cont := true for cont { scr.Clear() scr.Print(pagify(text, line)) scr.Print("\n\n(d/u scroll 30 lines; j/k: scroll 1 line; n/p scroll 1 page; q: quit)") scr.Refresh() a := scr.GetChar() switch goncurses.KeyString(a) { case "d": line += 30 break case "u": line -= 30 break case "j": line += 1 break case "k": line -= 1 break case "n": line += h break case "p": line -= h break case "q": cont = false break default: scr.DelChar() scr.DelChar() break } // Verify lines are not negative. Bad mojo if line < 0 { line = 0 } } doneWithInput = true } else { scr.Clear() scr.Print("\n\nPlease enter a number to select a comment\n\n") scr.Refresh() scr.GetChar() doneWithInput = true } case "o": if num, err := strconv.Atoi(input); err == nil { for num-1 > len(p.Articles) { p.GetNext() } viewInBrowser := exec.Command("xdg-open", p.Articles[num-1].Url) viewInBrowser.Start() doneWithInput = true } else { scr.Clear() scr.Print("\n\nPlease enter a number to view an article\n\n") scr.Refresh() doneWithInput = true } case "q": doneWithInput = true exit = true case "n": pageNum += 1 doneWithInput = true case "p": if pageNum > 0 { pageNum -= 1 } doneWithInput = true case "enter": continue case "backspace": //Not the prettiest but whatever cy, cx := scr.CursorYX() if len(input) > 0 { input = input[:len(input)-1] scr.MoveDelChar(cy, cx-3) scr.DelChar() scr.DelChar() } else { scr.MoveDelChar(cy, cx-2) scr.DelChar() scr.DelChar() } default: input += ch break } } } }