// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved. //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= package mop import ( `regexp` `strings` `github.com/nsf/termbox-go` ) type LineEditor struct { command rune prompt string cursor int input string screen *Screen quotes *Quotes } //----------------------------------------------------------------------------- func (self *LineEditor) Initialize(screen *Screen, quotes *Quotes) *LineEditor { self.screen = screen self.quotes = quotes return self } //----------------------------------------------------------------------------- func (self *LineEditor) Prompt(command rune) *LineEditor { prompts := map[rune]string{'+': `Add tickers: `, '-': `Remove tickers: `} if prompt, ok := prompts[command]; ok { self.prompt = prompt self.command = command self.screen.DrawLine(0, 3, `` + self.prompt + ``) termbox.SetCursor(len(self.prompt), 3) termbox.Flush() } return self } //----------------------------------------------------------------------------- func (self *LineEditor) Handle(ev termbox.Event) bool { defer termbox.Flush() switch ev.Key { case termbox.KeyEsc: return self.done() case termbox.KeyEnter: return self.execute().done() case termbox.KeyBackspace, termbox.KeyBackspace2: self.delete_previous_character() case termbox.KeyCtrlB, termbox.KeyArrowLeft: self.move_left() case termbox.KeyCtrlF, termbox.KeyArrowRight: self.move_right() case termbox.KeyCtrlA: self.jump_to_beginning() case termbox.KeyCtrlE: self.jump_to_end() case termbox.KeySpace: self.insert_character(' ') default: if ev.Ch != 0 { self.insert_character(ev.Ch) } } return false } //----------------------------------------------------------------------------- func (self *LineEditor) delete_previous_character() *LineEditor { if self.cursor > 0 { if self.cursor < len(self.input) { // Remove character in the middle of the input string. self.input = self.input[0 : self.cursor-1] + self.input[self.cursor : len(self.input)] } else { // Remove last input character. self.input = self.input[ : len(self.input)-1] } self.screen.DrawLine(len(self.prompt), 3, self.input + ` `) // Erase last character. self.move_left() } return self } //----------------------------------------------------------------------------- func (self *LineEditor) insert_character(ch rune) *LineEditor { if self.cursor < len(self.input) { // Insert the character in the middle of the input string. self.input = self.input[0 : self.cursor] + string(ch) + self.input[self.cursor : len(self.input)] } else { // Append the character to the end of the input string. self.input += string(ch) } self.screen.DrawLine(len(self.prompt), 3, self.input) self.move_right() return self } //----------------------------------------------------------------------------- func (self *LineEditor) move_left() *LineEditor { if self.cursor > 0 { self.cursor-- termbox.SetCursor(len(self.prompt) + self.cursor, 3) } return self } //----------------------------------------------------------------------------- func (self *LineEditor) move_right() *LineEditor { if self.cursor < len(self.input) { self.cursor++ termbox.SetCursor(len(self.prompt) + self.cursor, 3) } return self } //----------------------------------------------------------------------------- func (self *LineEditor) jump_to_beginning() *LineEditor { self.cursor = 0 termbox.SetCursor(len(self.prompt) + self.cursor, 3) return self } //----------------------------------------------------------------------------- func (self *LineEditor) jump_to_end() *LineEditor { self.cursor = len(self.input) termbox.SetCursor(len(self.prompt) + self.cursor, 3) return self } //----------------------------------------------------------------------------- func (self *LineEditor) execute() *LineEditor { switch self.command { case '+': tickers := self.tokenize() if len(tickers) > 0 { if added,_ := self.quotes.AddTickers(tickers); added > 0 { self.screen.Draw(self.quotes) } } case '-': tickers := self.tokenize() if len(tickers) > 0 { before := len(self.quotes.profile.Tickers) if removed,_ := self.quotes.RemoveTickers(tickers); removed > 0 { self.screen.Draw(self.quotes) after := before - removed for i := before; i > after; i-- { self.screen.ClearLine(0, i + 4) } if after == 0 { // Hide quotes header is the are no tickers left. self.screen.ClearLine(0, 4) } } } } return self } //----------------------------------------------------------------------------- func (self *LineEditor) done() bool { self.screen.ClearLine(0, 3) termbox.HideCursor() return true } //----------------------------------------------------------------------------- func (self *LineEditor) tokenize() []string { input := strings.ToUpper(strings.TrimSpace(self.input)) return regexp.MustCompile(`[,\s]+`).Split(input, -1) }