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()
}
Пример #2
0
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
}
Пример #3
0
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
			}
		}
	}
}